[英]Ruby metaprogramming: instance_eval and class_eval
Seems I am confused between the two methods though I have been using them for a while, I can't understand why the method passengers is not being added to the object in the following code: 尽管我已经使用了一段时间,但似乎对这两种方法感到困惑,我不明白为什么以下代码中没有将乘客方法添加到对象中:
class Bus
def number_of_seats
42
end
end
Bus.class_eval do
define_method :number_of_windows do
number_of_seats
end
def fuel_type
:diesel
end
end
Bus.instance_eval do
define_method :destination do
'Paris'
end
def passengers
12
end
end
bus = Bus.new
bus.number_of_windows # => 42
bus.fuel_type # => :diesel
bus.destination # => "Paris"
bus.passengers # => undefined method `passengers' (NoMethodError)
Notes : 注意事项 :
instance_eval
first, just randomly used class_eval
and then it too seemed to work! instance_eval
,只是随机使用class_eval
,然后它似乎也可以工作! instance_eval
's block: The code in the block is run with self
set to the object calling instance_eval
. instance_eval
的块的理解:块中的代码在将self
设置为调用instance_eval
的对象的instance_eval
。 class_eval
's block: The code in the block is evaluated as if its placed by opening the class of the object calling it. class_eval
块的理解:通过打开调用它的对象的类,对块中的代码进行评估,就好像放置了该代码一样。 Hence I am puzzled at the class_eval
in the above case! class_eval
感到困惑! I was expecting class_eval
on Bus would mean evaluating the block in the class
of Bus Class . class_eval
公交意味着评估在块class
总线类的。 You can refer this awesome article on class and instance_eval
as to why passengers is not being added to the object. 你可以参考这个阶级,真棒文章
instance_eval
,为什么乘客没有被添加到对象。
TL;DR: TL; DR:
Bus.class_eval will
create instance methods and Bus.instance_eval
will create class methods. Bus.class_eval will
创建实例方法,而Bus.instance_eval
将创建类方法。
Now, regarding the behavior of destination (which could be called on instance)..... define method when used inside either class_eval
or instance_eval
is immune to the usual behaviour . 现在,关于目标的行为(可以在实例上调用)..... define方法在
class_eval
或instance_eval
内部使用时, class_eval
通常行为的影响 。 Why?. 为什么?。
Because the documentation says so. 因为文档中是这样说的。 As per the documentation:
根据文档:
define method - Defines an instance method in the receiver.
define method-在接收方中定义一个实例方法。
Therefore, it does not matter if you use define_method
inside class_eval
or instance_eval
it would always create an instance method. 因此,如果在
class_eval
或instance_eval
使用define_method
class_eval
,它将始终创建一个实例方法。
Source for reference. 资料来源供参考。
Hope this helped :-). 希望这对您有所帮助:-)。
Basically you can't do an instance_eval
on a class object when using def
. 基本上,使用
def
时无法对类对象执行instance_eval
。 Here's a general way you use instance_eval
and class_eval
. 这是使用
instance_eval
和class_eval
的一般方法。 http://web.stanford.edu/~ouster/cgi-bin/cs142-winter15/classEval.php http://web.stanford.edu/~ouster/cgi-bin/cs142-winter15/classEval.php
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.