gpt4 book ai didi

ruby - instance_eval 的行为

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

我对 instance_eval 的理解是,如果我有模块 M,那么以下是等价的:

module M
def foo
:foo
end
end

class C
class << self
include M
end
end
puts C.foo

相当于:

module M
def foo
:foo
end
end

class C
end
C.instance_eval do
include M
end
puts C.foo

但是,第一个示例打印 :foo 而第二个示例抛出 NoMethodError? ( ruby 2.3.0)

在上述两种情况下,如果我更换了:

include M

与:

def foo
:foo
end

即直接定义方法而不是包含模块,那么这两种情况都会导致定义C.foo 方法。我应该对包含方法和直接定义方法之间的这种区别感到惊讶吗?或者在 instance_eval 的上下文中调用 include 是否有意义?它应该只在 class_eval 中调用吗?

最佳答案

在每种情况下,您要对什么对象调用 include?在您的第一个示例中,您在 C 的单例类上调用 include:

class C
class << self
p self == C.singleton_class
include M
end
end
# => true

p C.foo
# => :foo

...因此您的 include 行等效于 C.singleton_class.include(M)

然而,在您的第二个示例中,您在 C 本身上调用 include:

class C
end
C.instance_eval do
p self == C
include M
end
# => true

p C.foo
# => NoMethodError: undefined method `foo' for C:Class

p C.new.foo
# => :foo

...所以你正在执行与 C.include(M) 相同的操作,这与:

class C
p self == C
include M
end
# => true

p C.new.foo
# => :foo

像您希望的那样工作是在 C 的单例类上调用 instance_eval:

class D
end
D.singleton_class.instance_eval do
p self == D.singleton_class
include M
end
# => true

p D.foo
# => :foo

关于ruby - instance_eval 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44808061/

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