gpt4 book ai didi

ruby - 需要来自 "The Ruby Programming Language"的反射示例的帮助

转载 作者:数据小太阳 更新时间:2023-10-29 08:21:45 27 4
gpt4 key购买 nike

在这个来自 The Ruby Programming Language (p.270) 的例子中,我很困惑为什么 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")

最佳答案

Don't you use class_eval to define a class method and instance_eval when you want to define an instance method?

不幸的是,它并没有那么简单。

首先仔细看看class_eval的例子在做什么。 class_eval 是一个来自 Ruby 的 module class 的方法。 so 可以在任何类或模块上调用。当您使用 String.class_eval 时,您是在类的上下文中评估给定的代码。即,当您编写 String.class_eval("def len; size; end") 时,它就像您重新打开该类并键入传递给 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 class 中定义so 适用于任何 Ruby 对象。在一般情况下,它可用于向特定实例添加方法。例如如果我们有一个字符串 str 并说:

str.instance_eval("def special; size; end")

然后这将别名 specialsize 仅用于 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

关于ruby - 需要来自 "The Ruby Programming Language"的反射示例的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1388055/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com