Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
Run Code Online (Sandbox Code Playgroud)
只是基于方法的名称,我希望class_eval允许你向Foo和instance_eval添加一个类方法,以允许你向Foo添加一个实例方法.但他们似乎反其道而行之.
在上面的例子中,如果你在Foo类上调用class_bar,你会得到一个未定义的方法错误,如果你在Foo.new返回的实例上调用instance_bar,你也会得到一个未定义的方法错误.这两个错误似乎都与对class_eval和instance_eval应该做什么的直观理解相矛盾.
这些方法之间有什么区别?
class_eval的文档:
mod.class_eval(string [,filename [,lineno]])=> obj
在mod的上下文中计算字符串或块.这可以用于向类添加方法.
obj.instance_eval {| | block} => obj
在接收器(obj)的上下文中计算包含Ruby源代码或给定块的字符串.为了设置上下文,在代码执行时将变量self设置为obj,使代码可以访问obj的实例变量.