【问题标题】:What does this Rails Engine code mean: config.to_prepare &method(:activate).to_proc这个 Rails 引擎代码是什么意思:config.to_prepare &method(:activate).to_proc
【发布时间】:2011-02-24 11:14:31
【问题描述】:

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

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

  config.to_prepare &method(:activate).to_proc
end
  1. .to_prepare 做了什么
  2. &amp;method 运算符有什么作用?
  3. 代码的整体效果如何?

非常感谢!

【问题讨论】:

    标签: ruby-on-rails-3 spree


    【解决方案1】:

    &amp;method(:activate).to_proc

    最好一次食用一件。 (需要注意的是,这部分代码是 100% -Rails-specific Ruby。)

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

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

    查看以下 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/引擎。它在生产模式和开发中的每个请求上运行一次,并且是保证在开发模式下的每个请求上调用的唯一代码。如果您将修改类(class_eval 等)作为引擎初始化的一部分,这一点很重要;否则,您将在开发和生产中看到不同的行为。

    但是为什么呢?

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

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

    【讨论】:

    • 优秀的答案。只是想补充一点, config.to_prepare 东西是唯一保证在开发模式下的每个请求上都被调用的东西。如果您将类(class_eval 等)作为引擎初始化的一部分进行修改,这一点很重要。否则,您将在开发与生产中看到不同的行为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 2011-05-28
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多