Proc.new in Ruby: when do I need to use it?
The date_validator in its examples has a comment:
Using Proc.new prevents production cache issues
Does it mean, that everywhere in my code, where I use current time related methods (Time.now, 1.day.since(Time.zone.now), etc.) I should surround them with Proc.new { }?
I don't completely understand this开发者_JAVA百科, since replacing
time_now = Time.now.utc
with
time_now = Proc.new { Time.now.utc }
just doesn't make sense to me (new type of object is returned).
So, the question is, when and how should I use Proc.new with time related methods? And does that still apply to the latest versions of Ruby (1.92) and Rails (3.1)?
No, it only references the given example:
validates :expiration_date,
:date => {:after => Proc.new { Time.now },
:before => Proc.new { Time.now + 1.year } }
If instead you'd written
validates :expiration_date,
:date => {:after => Time.now,
:before => Time.now + 1.year }
Time.now
would be interpreted when the class is parsed and it would be validating against that value.
Using Proc.new in that validation means Time.new will be evaluated when the validation is actually run - not when it's initially being interpreted.
What Proc.new (and lambda) does is, save all your statements in their original form (in an anonymous function), and doesn't evaluate them.
Date Validator gem must have some kind of test to check if a Proc was passed, and it evaluates it when it's actually validating the stuff.
Edit: It does this here - 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)
A quick example :
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)>
Note that this will only work with libraries that do implement this kind of check, and not every function accepting a Time
.
精彩评论