我理解proc的概念,但有时我会看到这样的代码(请参阅rails指南进行验证http://guides.rubyonrails.org/active_record_validations_callbacks.html#using-if-and-unless-with-a-proc):
class Order < ActiveRecord::Base
before_save :normalize_card_number,
:if => Proc.new { |order| order.paid_with_card? }
end
这似乎可以更简单地写为:
class Order < ActiveRecord::Base
before_save :normalize_card_number, :if => :paid_with_card?
end
在这里使用Proc的优点是什么?
thx提前
在简单的情况下,它们是等效的,但proc允许更多的多功能性,而不需要简单地为验证if check定义方法。
想象一下:
before_save :nuke, :if => Proc.new { |model| !model.nuked? && model.nukable? && model.region.nukable? }
您总是可以在实例方法中写入该检查并用符号引用它,但对于特定逻辑仅在中的情况:if,将其保留在proc中是有效的。
如果方法的接收器是要验证的对象,则它们是等效的。这并不完全是ActiveModel验证器的工作方式,但概念类似:
在符号:sym
上调用to_proc
可以获得->(x){x.sym}的功能等价物-符号将作为消息发送到proc的参数。在proc上调用to_proc
只会返回自身,因此您可以将符号或proc传递到方法中,并保证proc:
def return_a_proc(symbol_or_proc)
symbol_or_proc.to_proc
end
在模型实例不是接收器的情况下,例如验证方法将模型作为参数,或者像Daniel Evans的例子一样,您需要显式地构造proc,以指定应该对proc的参数执行什么操作。