4

我了解 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 的优势,我没有得到什么?

提前谢谢

4

2 回答 2

5

在简单的情况下,它们是等价的,但是 procs 允许更多的多功能性,而不需要简单地定义一个方法来进行验证 if 检查。

想象一下:

before_save :nuke, :if => Proc.new { |model| !model.nuked? && model.nukable? && model.region.nukable? }

您始终可以在实例方法中编写该检查并用符号引用它,但是对于特定逻辑仅在 :if 中的情况,将其保留在 proc 中是有效的。

于 2013-02-19T17:17:33.867 回答
1

如果方法的接收者是被验证的对象,它们是等价的。这并不是ActiveModel验证器的工作方式,但概念是相似的:

调用to_proc符号:sym为您提供 ->(x){ x.sym } 的功能等价物 - 符号作为消息发送到 proc 的参数。调用to_procproc 只会返回自身,因此您可以将符号或 proc 传递给方法并保证 proc:

def return_a_proc(symbol_or_proc)
  symbol_or_proc.to_proc
end

在模型实例不是接收者的情况下,例如验证方法将模型作为参数,或者在 Daniel Evans 的示例中,您需要显式构造 proc 以指定应该使用 proc 的参数做什么。

于 2013-02-19T17:28:02.027 回答