这个Rails引擎代码意味着什么:config.to_prepare& method(:activate).to_proc

时间:2011-02-24 11:14:31

标签: ruby-on-rails-3 spree

我正在使用Spree,它广泛使用Rails引擎。我发现的常见模式是这个。但是我无法理解这段代码。

class Engine < Rails::Engine 
  def self.activate
    ...
  end     

  config.to_prepare &method(:activate).to_proc
end
  1. .to_prepare做什么
  2. &method运营商做了什么?
  3. 代码的整体效果是什么?
  4. 非常感谢!

1 个答案:

答案 0 :(得分:37)

<强> &method(:activate).to_proc

这是最好一次消耗一件物品。 (应该注意的是,这部分代码是100% -Rails特定的Ruby。)

method是一个Ruby方法(它都是非常元)。它is documented thusly

  

将命名方法查找为   obj中的接收器,返回一个Method   object(或引发NameError)。该   方法对象充当闭包   obj的对象实例,所以实例   变量和自我的价值保持不变   可用。

查看以下IRB会话:

ruby-1.9.2-p136 :001 > def my_method
ruby-1.9.2-p136 :002?>   puts "in my_method"
ruby-1.9.2-p136 :003?>   10
ruby-1.9.2-p136 :004?>   end
 => nil 
ruby-1.9.2-p136 :005 > method(:my_method)
 => #<Method: Object#my_method>

因此,method调用正在查找(在您的示例中)activate方法,并为其创建Method objectMethod包含一个名为to_proc的方法,其中包含“returns a Proc object corresponding to this method”。继续我们的IRB会议:

ruby-1.9.2-p136 :006 > method(:my_method).to_proc
 => #<Proc:0x000001010a3e38 (lambda)>

最后,我们使用&符运算符,当在方法调用期间在Proc对象之前时,它将被Proc包含的块替换。再一次在IRB:

ruby-1.9.2-p136 :007 > def executor(&block)
ruby-1.9.2-p136 :008?>   block.call
ruby-1.9.2-p136 :009?>   end
 => nil 
ruby-1.9.2-p136 :010 > executor( &method(:my_method).to_proc )
in my_method
 => 10

所以,在伪代码中,你列出的行是:

config.to_prepare(a block containing the functionality of the method activate)

<强> config.to_prepare

[根据schof的评论编辑]

config.to_prepare需要运行一个块来设置您的Railtie / Engine。它在生产模式和开发中的每个请求上运行一次,并且保证在开发模式下的每个请求上都可以调用唯一的代码。如果要在引擎初始化过程中修改类(class_eval等),这很重要;否则,你会看到开发与生产中的不同行为。

但为什么?

这是一个常见习语的原因是您不必在to_prepare块本身内定义准备代码;您可以在类中定义方法,然后使用上述魔法将它们转换为块(记住其范围)。该代码在功能上等同于:

class Engine < Rails::Engine 
  config.to_prepare do
    (the contents of self.activate)
  end
end