需要帮助“Ruby编程语言”中的reflection示例
在这个来自Ruby Programming Language (p.270)的instance_eval
,我很困惑为什么示例代码最后一行的instance_eval
方法定义了一个名为String.empty
的类方法 。
如果要定义实例方法,是否不要使用class_eval
定义类方法和instance_eval
?
o.instance_eval("@x") # Return the value of o's instance variable @x # Define an instance method len of String to return string length String.class_eval("def len; size; end") # Here's another way to do that # The quoted code behaves just as if it was inside "class String" and "end" String.class_eval("alias len size") # Use instance_eval to define class method String.empty # Note that quotes within quotes get a little tricky... String.instance_eval("def empty; ''; end")
如果要定义实例方法,是否不要使用
class_eval
定义类方法和instance_eval
?
不幸的是,它并不那么简单。
首先仔细看看class_eval
的例子是做什么的。 class_eval
是一个来自Ruby 模块类的方法,因此可以在任何类或模块上调用。 使用String.class_eval
您将在类的上下文中评估给定的代码。 即当你编写String.class_eval("def len; size; end")
它就像你重新打开类并输入传递给class_eval
的代码class_eval
例如
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的Object类中定义,因此可以在任何Ruby对象上使用。 在一般情况下,它可用于向特定实例添加方法。 例如,如果我们有一个String str
并说:
str.instance_eval("def special; size; end")
然后,这将为special
的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
这是一般主题:
使用ClassName.instance_eval定义单例方法。
使用ClassName.class_eval定义实例方法。
这篇文章有一个非常巧妙的解释,试一试……