class_evalとinstance_eval
以下のようなクラスとインスタンスについて考えていく。
Person = Class.new # Personクラスの作成(Classクラスのインスタンスの作成)
naoty = Person.new # Personクラスのインスタンスの作成
今回はclass_evalとinstance_evalについて。どっちとも引数のブロック内の文字列をRubyコードとして評価して実行するのだが、実行するコンテキストが異なる。
Person.class_eval do
def greet
p 'Hello, my world!'
end
end
naoty.greet #=> "Hello, my world!"
- class_evalはレシーバ(=Person)をクラスとしてブロック内を実行する。クラス内で実行されたのと同じ。
- この場合、Personをクラスとしてgreetを定義しているので、greetはインスタンスメソッドとなり、naotyというインスタンスから呼び出すことができる。
- privateメソッドを呼び出すときに使われることが多い。
Person.instance_eval do
def greet
p 'Hello, world!'
end
end
Person.greet #=> "Hello, world!"
naoty.greet #=> NoMethodError: undefined method 'greet' for ...
- instance_evalはレシーバ(=Person)をインスタンスとしてブロック内を実行する。
- instance_evalでメソッドを定義すると、そのインスタンスの特異メソッドが定義されることになる。
- PersonをClassクラスのインスタンスとして考えると、instance_eval内で定義されたメソッドはPersonの特異メソッドであり、すなわちクラスメソッドということになる。