[Ruby]インスタンスメソッドとクラスメソッド
よく混乱するので復習もかねてまとめた。まとめたけどこれからも何度も振り返ることになりそう。
インスタンスメソッド
クラス構文の内部でメソッドを定義するとインスタンスメソッドになる。名前の通り、そのクラスに属するインスタンス(オブジェクト)に対して呼び出すことができる。
class クラス名
def メソッド名
end
end
メソッドの呼び出し↓
インスタンス名.メソッド名
<例>
class Drink
def name
"coffee"
end
end
drink = Drink.new # Drinkクラスのオブジェクトを作成
puts drink.name #=> coffee
引数を渡すこともできる。
class Drink
def order(name)
puts "#{name}をください"
end
end
drink = Drink.new # Drinkクラスのオブジェクトを作成
drink.order("コーヒー") #=> コーヒーをください
インスタンス変数
メソッドやブロックの内部で作成される変数のことをローカル変数と呼ぶ。ローカル変数はメソッドやブロックの内部でのみ有効である。
一方インスタンス変数はローカル変数より広いスコープを持ち、同じインスタンス(オブジェクト)であれば複数のメソッドをまたいで使うことができる。インスタンス変数は変数名の先頭に@をつけて作成する。
class Drink
def order(item)
puts "#{item}をください"
@name = item
end
def reorder
puts "もう1杯#{@name}をください"
end
end
drink = Drink.new
drink.order("コーヒー") #=> コーヒーをください
drink.reorder #=> もう1杯コーヒーをください
しかしこのままだとインスタンス変数はクラスの外部から参照することができない。参照したい場合は@nameを戻り値とするメソッドを作る必要がある。
class Drink
def order(item)
puts "#{item}をください"
@name = item
end
def name
@name
end
end
drink = Drink.new
drink.order("コーヒー") #=> コーヒーをください
puts drink.name #=> コーヒー
インスタンス変数を取得するメソッドは慣習的にインスタンス変数名から@を取り除いたものにすることが多い。
なお、この3行↓は
def name
@name
end
次の1行のように短く書くことができる。
attr_reader :name
attr_readerは同名のインスタンス変数を戻り値とするメソッドを定義するメソッドである。
参照するだけでなく外部から変更したい場合も変更用のメソッドを定義する必要がある。=で終わるメソッドを定義すると、変数に代入するような形式でそのメソッドを呼び出すことができる。慣習的に、インスタンス変数名から@を取り、末尾に=を加えたものにすることが多い。
class Drink
def name=(text)
@name = text #=> 引数として渡された"コーヒー"をインスタンス変数@nameへ代入する
end
def name
@name
end
end
drink = Drink.new
drink.name= "コーヒー" #=> name=メソッドを呼び出し引数として"コーヒー"を渡す
puts drink.name #=> コーヒー
メソッド呼び出しのdrink.name= "コーヒー"は、
drink.name = "コーヒー"
と=の前に半角スペースを空けて書くこともできる。
また、この3行↓は
def name=(text)
@name = text
end
次の1行で書くことができる。
attr_writer :name
attr_writerは同名のインスタンス変数へ代入するメソッドを定義するメソッドである。そしてattr_reader :nameとattr_writer :nameをあわせて、
attr_accessor :name
と書き換えることができる。
カンマで区切って複数の引数を渡すこともできる。
attr_accessor :name, :price
initializeメソッド
initializeという名前のメソッドを作ると、オブジェクトが新しく作成されたときに(newメソッドを呼び出したときに)自動で呼び出される。
class Drink
def initialize
puts "Initialized!"
end
end
Drink.new #=> Initialized!
initializeメソッドは特殊なメソッドで、デフォルトでprivateメソッドになっているため外部から呼び出すことはできない。
class Drink
def initialize
@name = "coffee"
end
def name
@name
end
end
drink = Drink.new
puts drink.name #=> coffee
クラスメソッド
クラスに作るメソッドには、インスタンスメソッドとクラスメソッドの2種類ある。
クラスメソッドの定義方法は2通りある。
class クラス名
def self.クラスメソッド
# クラスメソッドの処理
end
end
以下のように書くこともできる。ネストは深くなるがたくさんのクラスメソッドを定義したい場合は毎回self.を書かなくて済む。
class クラス名
class << self
def クラスメソッド
# クラスメソッドの処理
end
end
end
呼び出すとき↓
クラス名.メソッド名
<例>
class Cafe
def self.welcome
"いらっしゃいませ"
end
end
puts Cafe.welcome #=> いらっしゃいませ
クラスに関連は深いが、ひとつひとつのインスタンスに含まれるデータは使わないメソッドを定義したいような場合に、クラスメソッドを定義すると使い勝手が良くなる。