简体   繁体   中英

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, 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM