3

示例中的date_validator有一条评论:

Using Proc.new prevents production cache issues

这是否意味着,在我的代码中的任何地方,我使用当前时间相关的方法(Time.now、1.day.since(Time.zone.now) 等)我都应该用 Proc.new { } 包围它们?

我不完全理解这一点,因为更换

time_now = Time.now.utc

time_now = Proc.new { Time.now.utc }

对我来说没有意义(返回新类型的对象)。

所以,问题是,我应该何时以及如何将 Proc.new 与时间相关的方法一起使用?这仍然适用于 Ruby (1.92) 和 Rails (3.1) 的最新版本吗?

4

2 回答 2

5

不,它仅引用给定的示例:

validates :expiration_date,
  :date => {:after => Proc.new { Time.now },
  :before => Proc.new { Time.now + 1.year } }

相反,如果你写

validates :expiration_date,
  :date => {:after => Time.now,
  :before => Time.now + 1.year }

Time.now将在解析类时进行解释,并将针对该值进行验证。

在该验证中使用 Proc.new 意味着 Time.new 将在验证实际运行时进行评估 - 而不是在最初解释时。

于 2011-06-19T15:38:08.987 回答
3

Proc.new(和 lambda)所做的是,以原始形式(在匿名函数中)保存所有语句,并且不评估它们。

Date Validator gem 必须进行某种测试来检查 Proc 是否通过,并在实际验证内容时对其进行评估。

编辑:它在这里执行此操作 - https://github.com/codegram/date_validator/blob/master/lib/active_model/validations/date_validator.rb#L47

option_value = option_value.call(record) if option_value.is_a?(Proc)

一个简单的例子:

pry(main)> time_now = Time.now
=> 2011-06-19 21:07:07 +0530
pry(main)> time_proc = Proc.new { Time.now }
=> #<Proc:0x9710cc4@(pry):1>
pry(main)> time_proc.call
=> 2011-06-19 21:07:28 +0530
pry(main)> time_proc.call
=> 2011-06-19 21:07:31 +0530
pry(main)> 

请注意,这仅适用于实现这种检查的库而不是每个接受Time.

于 2011-06-19T15:38:41.303 回答