需要“Ruby 编程语言”中的反射示例帮助

2024-04-30

在这个例子中来自Ruby 编程语言(第270页),我很困惑为什么instance_eval示例代码最后一行的方法定义一个类方法 called 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 的方法模块类 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要“Ruby 编程语言”中的反射示例帮助 的相关文章

随机推荐