Ответ 1
&method(:activate).to_proc
Это лучше всего потребляется по одному пункту за раз. (Следует отметить, что эта часть кода - это 100% не-Rails-специфичный Ruby.)
method
- это метод Ruby (все это очень мета). Это задокументировано:
Вызывает именованный метод как приемник в obj, возвращая метод объект (или повышение NameError). Объект метода действует как замыкание в экземпляр объекта objs, поэтому экземпляр переменные и значение 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
объект. method
содержит метод под названием to_proc
, который "возвращает объект Proc, соответствующий этому методу". Продолжая нашу сессию 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