今日の教科書
クラスとモジュール
#メモ
##クラス
全てのオブジェクトは何かのクラスに所属している。
new
:新しいオブジェクトを作るために使う。
ary = Array.new
p ary #=> []
str = String.new
p str #=> ""
クラスに属しているオブジェクトを作れる、このようなオブジェクトをインスタンスともいう。
class
:オブジェクトが属しているクラスを知る。
ary = Array.new
p ary.class #=> Array
##クラスの定義
Rubyには最初から組み込まれているクラスがある。別に新しく定義もできる。
class <クラス名>
<クラスの定義>
end
クラス名の最初は大文字。
class HelloRuby
def hello
puts("Hello, Ruby!")
end
end
greeting = HelloRuby.new
greeting.hello
##initializeメソッド
クラス内にinitializeを定義するとnewでインスタンスを作るときにinitializeが呼ばれる。
newに渡した引数がinitializeの引数になる。インスタンスの初期化の設定の際に、クラス内に定義して使う。
class Person
# 引数に値を代入すると、デフォルト値を設定できる
def initialize(name="Bob")
@name = name
end
def name
puts(@name)
end
end
bob = Person.new
bob.name #=> Bob
john = Person.new("John")
john.name #=> John
インスタンスを初期化しない場合は定義しなくていい。
##インスタンス変数
「@」がついている変数のこと。インスタンス変数はクラス内の異なるメソッドの間でも値の受け渡しができる。インスタンス変数はインスタンスごとに異なる値を扱える。
class Foo
def initialize(arg)
@foo = arg
end
def foo
puts @foo
end
def bar
puts @foo
end
end
foo = Foo.new("foo")
foo.foo #=> foo
foo.bar #=> foo
bar = Foo.new("bar")
bar.foo #=> bar
foo.bar #=> bar
# 異なる値をインスタンス変数に代入している
foo.foo #=> foo
##インスタンスメソッド
クラス内で定義したメソッドはインスタンスメソッドとして扱われる。そして、newでインスタンスを作ったときにそのインスタンスに追加される。インスタンスメソッドはインスタンスに対する操作を目的としているので、インスタンスをレシーバにして呼び出す。
class Foo
def foo
puts("foo")
end
end
instance = Foo.new
instance.foo #=> foo
##アクセスメソッド
オブジェクト内のインスタンス変数を外部から操作することはできない。
そのため、専用のメソッドを定義する必要がある。
class Person
def name
return @name
end
def name=(value)
@name = value
end
end
nameとname=は別。name
:インスタンス変数の値を知るためのメソッド。
name=
:インスタンス変数に代入するメソッド。
class Person
def name
return @name
end
def name=(value)
@name = value
end
end
john = Person.new
john.name = "John"
p john.name #=> John
bob = Person.new
bob.name = "Bob"
p bob.name #=> Bob
このようにRubyのオブジェクトが持っているインスタンス変数の値を調べるにはメソッドを定義しないといけません。そのため、このようなメソッドを定義するための機能がRubyには用意されています。attr_reader :method 参照のみ可能にする
attr_writer :method 変更のみ可能にする
attr_accessor :method 参照と変更の両方を可能にする
アクセスメソッドと呼び、クラス内に定義すると引数に指定したメソッド名と同じ名前のインスタンス変数とメソッドが定義される。そのメソッドを呼び出して、つくられたインスタンス変数を扱う。
class Greeting
attr_reader :hello
attr_writer :bye
attr_accessor :pardon
end
greeting = Greeting.new
greeting.hello #=> nil
greeting.bye = 42
greeting.pardon = "sorry"
p greeting.pardon #=> sorry
###末尾の記号
- 等号 (=)
- 疑問符 (?)
- 感嘆符 (!)
これらをメソッドに定義するときにつけることができる。
これらの記号をメソッド名の末尾に付けたメソッドは、どのような機能を持っているのかを表しています。ただし、記号が表しているメソッドの機能を備えていたとしても、必ずメソッド名の末尾に記号が付いているわけではありません。
####等号
メソッドの末尾につけると代入できることを表す。アクセスメソッドと同様、セッターメソッド。
class Person
# メソッド名の末尾に「=」がないメソッド定義
def result(value)
@name = value
end
end
bob = Person.new
# この形式で値を変更できない
bob.result = "Bob"
NoMethodError: undefined method `result=' for #<Person:0xb7bdb520>
from (irb):11
from :0
####疑問符
メソッドの末尾につけると真偽値を返すことを表す。
p @foo #=> nil
p @foo.nil? #=> true
@foo = "foo"
p @foo.nil? #=> false
####感嘆符
レシーバを変えるメソッドは破壊的なメソッドとよぶ。このメソッドの末尾に!をつける習慣がある。
あくまで習慣なので全てについているわけではない。
破壊的なメソッドは、レシーバのコピーを作ってそちらの状態を変更するよりも効率がよいように見えますが、副作用が思わぬ問題を引き起こすかもしれません。たとえば文字列の文末にある空白文字を取り除くchopメソッドがあります。
text = "abcde "
# メソッド呼出し
p text.chop #=> "abcde"
p text #=> "abcde "
# 破壊的なメソッド呼出し
p text.chop! #=> "abcde"
p text #=> "abcde"
##クラスメソッド
クラスに対する操作を行うことを目的としたメソッドをクラスメソッドという。
- def クラス名.メソッド名 〜 end
- class << クラス名 〜 def メソッド名 〜 end end
- class クラス名 〜 def self.メソッド名 〜 end end
このやり方でクラスメソッドを定義できる。
###「def クラス名.メソッド名 〜 end」
class HelloRuby
def HelloRuby.greeting
puts("Hello! Ruby!")
end
end
HelloRuby.greeting #=> Hello! Ruby!
###class << クラス名 〜 def メソッド名 〜 end end
class HelloRuby
def foo
puts("foo")
end
end
class << HelloRuby
def greeting
puts("Hello! Ruby!")
end
end
HelloRuby.greeting #=> Hello! Ruby!
###class クラス名 〜 def self.メソッド名 〜 end end
class HelloRuby
def self.greeting
puts("Hello! Ruby!")
end
end
HelloRuby.greeting #=> Hello! Ruby!