gpt4 book ai didi

带有 attr_accessor 的类上的 Ruby instance_eval

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

我了解 instance_evalclass_eval 之间的基本区别。我在玩弄时发现的是一些涉及 attr_accessor 的奇怪东西。这是一个例子:

A = Class.new
A.class_eval{ attr_accessor :x }

a = A.new
a.x = "x"
a.x
=> "x" # ... expected

A.instance_eval{ attr_accessor :y }

A.y = "y"
=> NoMethodError: undefined method `y=' for A:Class

a.y = "y"
=> "y" # WHATTT?

这是怎么回事:

  1. instance_eval 没有访问我们的 A 类(对象)
  2. 然后它实际上将它添加到 A 的实例中?

最佳答案

首先,你的理解(或直觉)是正确的,#instance_eval#class_eval中定义的方法不一样

A = Class.new

A.instance_eval { def defined_in_instance_eval; :instance_eval; end }
A.class_eval { def defined_in_class_eval; :class_eval; end }

A.new.defined_in_class_eval # => :class_eval
A.defined_in_instance_eval # => :instance_eval

旁注:虽然 selfinstance_evalclass_eval 中相同,但默认定义 不同,见http://yugui.jp/articles/846

真正起作用的是 Module#attr_accessor 本身,看看它的定义: http://rxr.whitequark.org/mri/source/vm_method.c#620

它不使用def,它不读取上下文、self 或默认定义者。它只是“手动”将方法插入模块。这就是结果违反直觉的原因。

关于带有 attr_accessor 的类上的 Ruby instance_eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14428531/

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