简体   繁体   English

Ruby元编程:instance_eval和class_eval

[英]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 : 注意事项

  • Tried instance_eval first, just randomly used class_eval and then it too seemed to work! 首先尝试instance_eval ,只是随机使用class_eval ,然后它似乎也可以工作!
  • My understanding of 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
  • My understanding of 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_evalinstance_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_evalinstance_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_evalclass_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM