示例中的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)吗?
答案 0 :(得分: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,而不是在最初解释它时。
答案 1 :(得分:3)
Proc.new(和lambda)所做的是,以原始形式(在匿名函数中)保存所有语句,并且不对它们进行评估。
日期验证器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
的函数。