Han*_*nXu 20 ruby ruby-on-rails
我对rails如何实现过滤器感兴趣before_filter.
但在阅读完源代码后,我仍然感到困惑.
我注意到rails的框架维护了一个filter_chain,并在目标方法之前运行过滤器.
但是,我不明白一个重要的过程:rails如何捕获一个方法调用?
我的意思是,例如,我有一个类Dog,并设置before_filter方法树皮.
当我调用时dog.bark,rails应该以某种方式捕获此调用,并改为运行其修改的方法.
但是,我在源代码中找不到这样的代码.
任何人都可以告诉我这个想法或指出代码所在的位置吗?
dee*_*our 22
当您设置一个before_filter,或任何类似的过滤器(想想after_filter,around_filter),你用或者是这样的符号或PROC,拉姆达或块.
before_filter :bark
before_filter Proc.new { |k| k.bark }
Run Code Online (Sandbox Code Playgroud)
上述追加符号或块的堆叠这里,通过调用set_callback.这构建了您所指的"链".
此"链"中的每个项目都是ActiveSupport::Callbacks::Callback该类的实例.这堂课知道
:bark方法)Dog班级)该Callback实例被附加到一个ActiveSupport::Callbacks::CallbackChain在__update_callbacks.
当每个Callback类进行初始化,_compile_filter运行以从所述过滤器正常化Symbol,Proc,λ,或块分割成一个共同的,可调用的格式.
最后,当CallbackChain运行时,它将调用start每个Callback实例,此时它将在适当的上下文中实际执行过滤器.
重要的是要指出你不会创建像这样的过滤器
before_filter dog.bark
Run Code Online (Sandbox Code Playgroud)
这将执行dog.bark并传递它的返回值以before_filter附加到CallbackChain.目的是before_filter为Rails 传递某种指令,以便稍后为您执行.你会做类似的事情
before_filter Proc.new { d = Dog.new; d.bark }
Run Code Online (Sandbox Code Playgroud)
其中的代码Proc未执行.当上面的行由Rails运行时.相反,Rails被告知要传递Proc给CallbackChain.这Proc是您传递给Rails以在适当时间执行的"指令".
铁轨如何知道我曾经称之为:树皮
至于这个,假设你的Dog课程被简单定义为
class Dog
def bark
end
def eat
end
end
Run Code Online (Sandbox Code Playgroud)
(虽然这是一个可怕的例子),你可能想要有类似的东西
before_bark :eat
Run Code Online (Sandbox Code Playgroud)
这需要您定义bark回调,然后告诉您的bark方法运行相关的bark回调.
class Dog
extend ActiveModel::Callbacks
define_callbacks :bark
before_bark :eat
def bark
run_callbacks(:bark) { YOUR BARK CODE HERE }
end
def eat
end
end
Run Code Online (Sandbox Code Playgroud)
你可以看到这ActiveRecord::Callbacks是怎么回事.
这确实是一个糟糕的例子,因为你可以(并且应该)eat直接从中 调用bark,但这应该得到重点.
| 归档时间: |
|
| 查看次数: |
7459 次 |
| 最近记录: |