带有 attr_accessor 的类上的 Ruby instance_eval

标签 ruby attr-accessor class-eval instance-eval

我了解 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/

相关文章:

ruby-on-rails - 为什么在重新打开类(class)时有时会使用 class_eval?

ruby-on-rails - ruby on rails 服务器不会开始丢失设计文件

ruby 和重音字符

ruby-on-rails - 为什么在安装 Rails 时出现 "write permission"错误?

amazon-s3 - 在 Heroku 上使用回形针和 S3 上传时,模型缺少 'photo_file_name' 所需的 attr_accessor

ruby-on-rails - 当我将数据放在 :notes and :place, 上时,验证仍然失败

ruby - 在放置前按下 shift|control 键拖放对象

ruby-on-rails - 使用 attr_accessor 缓存模型数组?

ruby - class_eval 与 instance_eval

ruby - 你怎么临时 "class_eval"作测试?