带有attr_accessor的类上的Ruby instance_eval

bra*_*rad 5 ruby instance-eval attr-accessor class-eval

我理解instance_eval和之间的基本区别class_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?
Run Code Online (Sandbox Code Playgroud)

怎么样:

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

Dan*_*nov 7

首先,你的理解(或直觉)是正确的,里面定义的方法#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
Run Code Online (Sandbox Code Playgroud)

一个侧面说明:虽然self是相同的两个instance_evalclass_eval默认definee不同的是,看到http://yugui.jp/articles/846

究竟是什么诀窍Module#attr_accessor本身,看看它的定义:http: //rxr.whitequark.org/mri/source/vm_method.c#620

它不使用def,它不读取上下文self或默认的definee.它只是"手动"将方法插入到模块中.这就是结果违反直觉的原因.