Proc.new в Ruby: когда мне нужно его использовать? - PullRequest
3 голосов
/ 19 июня 2011

У 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)?

Ответы [ 2 ]

5 голосов
/ 19 июня 2011

Нет, он ссылается только на данный пример:

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 будет оцениваться при фактическом выполнении проверки, а не при первоначальной интерпретации.

3 голосов
/ 19 июня 2011

То, что делает Proc.new (и лямбда), сохраняет все ваши утверждения в их первоначальном виде (в анонимной функции) и не оценивает их.проверка, чтобы проверить, был ли пройден 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.

...