你不使用class_eval
定义一个
类方法和instance_eval
什么时候
你想定义一个实例方法吗?
不幸的是,事情并不那么简单。
首先仔细看看例子是什么class_eval
是做。class_eval
是一个来自 Ruby 的方法模块类 http://www.ruby-doc.org/core/classes/Module.html#M001650so 可以在任何类或模块上调用。当你使用String.class_eval
您正在类的上下文中评估给定的代码。即当你写String.class_eval("def len; size; end")
这就像你重新打开类并输入传递给的代码一样class_eval
e.g.
class String
def len
size
end
end
因此,要使用 class_eval 添加类方法,您可以编写String.class_eval("def self.empty; ''; end")
其效果与以下相同:
class String
def self.empty
''
end
end
instance_eval
是在 Ruby 中定义的对象类 http://www.ruby-doc.org/core/classes/Object.html#M000334so 可用于任何 Ruby 对象。在一般情况下,它可用于向特定实例添加方法。例如如果我们有一个字符串str
并说:
str.instance_eval("def special; size; end")
然后这将别名special
to size
只为str
但不适用于任何其他 String 对象:
irb(main):019:0> "other".special
NoMethodError: undefined method `special' for "other":String
from (irb):19
要理解 String.instance_eval 发生了什么,请记住 String 类本身就是一个对象(该类的实例)Class
)并且定义的每个类都有这样一个单例实例对象。当你使用String.instance_eval
您正在评估给定的代码String
实例对象。即,它相当于重新打开 String 的元类并键入传递的代码,例如
class String
class << self
def empty
''
end
end
end