x.instance_eval
コンテキストを変更するため、self
に評価されx
ます。
これにより、インスタンス変数やインスタンス メソッドを定義するなど、多くのことが可能になりますが、x に対してのみです。
x = Object.new
y = Object.new
# define instance variables for x and y
x.instance_eval { @var = 1 }
y.instance_eval { @var = 2 }
# define an instance method for all Objects
class Object
def var
@var
end
end
x.var #=> 1
y.var #=> 2
Ruby では、いくつかの場所でオブジェクトのインスタンス メソッドを定義できます。通常、それらはクラスで定義され、それらのインスタンス メソッドはそのクラスのすべてのインスタンス間で共有されます (def var
上記のように)。
ただし、単一のオブジェクトに対してインスタンス メソッドを定義することもできます。
# here's one way to do it
def x.foo
"foo!"
end
# here's another
x.instance_eval do
# remember, in here self is x, so bar is attached to x.
def bar
"bar!"
end
end
x
とは同じクラスを持っていますy
が、 に対してのみ定義されているため、これらのメソッドを共有していませんx
。
x.foo #=> "foo!"
x.bar #=> "bar!"
y.foo #=> raises NoMethodError
y.bar #=> raises NoMethodError
Ruby では、クラスでさえも、すべてがオブジェクトです。クラス メソッドは、そのクラス オブジェクトの単なるインスタンス メソッドです。
# we have two ways of creating a class:
class A
end
# the former is just syntatic sugar for the latter
B = Class.new
# we have do ways of defining class methods:
# the first two are the same as for any other object
def A.baz
"baz!"
end
A.instance_eval do
def frog
"frog!"
end
end
# the others are in the class context, which is slightly different
class A
def self.marco
"polo!"
end
# since A == self in here, this is the same as the last one.
def A.red_light
"green light!"
end
# unlike instance_eval, class context is special in that methods that
# aren't attached to a specific object are taken as instance methods for instances
# of the class
def example
"I'm an instance of A, not A itself"
end
end
# class_eval opens up the class context in the same way
A.class_eval do
def self.telegram
"not a land shark"
end
end
繰り返しますが、これらのメソッドはすべてA
固有のものでB
あり、それらのいずれにもアクセスできないことに注意してください。
A.baz #=> "baz!"
B.telegram #=> raises NoMethodError
ここで重要なことは、クラス メソッドはクラスのオブジェクトの単なるインスタンス メソッドであるということです。Class