带有attr_accessor的类上的Ruby instance_eval [英] Ruby instance_eval on a class with attr_accessor

查看:78
本文介绍了带有attr_accessor的类上的Ruby instance_eval的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解instance_evalclass_eval之间的基本区别.尽管我在玩游戏时发现的是涉及attr_accessor的奇怪现象.这是一个示例:

I understand the basic difference between instance_eval and class_eval. What I've discovered though when playing around is something strange involving attr_accessor. Here's an example:

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内部定义的方法不相同

At first, your understanding (or intuition) is correct, methods defined inside #instance_eval and #class_eval are not the same

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中都相同,但默认定义是不同的,请参见

a side note: while self is the same in both instance_eval and class_eval, the default definee is different, see http://yugui.jp/articles/846

真正的诀窍是Module#attr_accessor本身,看一下它的定义: http://rxr.whitequark.org/mri/source/vm_method.c#620

What really does the trick is Module#attr_accessor itself, look at its definition: http://rxr.whitequark.org/mri/source/vm_method.c#620

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

it does not use def, it does not read context, self or a default definee. It just "manually" inserts methods into a module. That's why the result is counterintuitive.

这篇关于带有attr_accessor的类上的Ruby instance_eval的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆