【问题标题】:Proc.new in Ruby: when do I need to use it?Ruby 中的 Proc.new:我什么时候需要使用它?
【发布时间】:2011-06-19 15:33:36
【问题描述】:

示例中的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) 的最新版本?

【问题讨论】:

    标签: ruby-on-rails ruby proc-object


    【解决方案1】:

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

    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 将在验证实际运行时进行评估 - 而不是在最初解释时。

    【讨论】:

      【解决方案2】:

      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 的函数。

      【讨论】:

      • 谢谢。我发现延迟工作 (github.com/collectiveidea/delayed_job) 也实现了这一点。与 date_validator 不同,我在单独的方法中创建新作业(每次都应该运行)。这是否意味着,在这种情况下 Proc.new {} 是可选的并且没有任何区别?
      • @krn,使用直接 Time.now 的问题是您的 Time.now 将在 何时 首次加载应用程序时进行评估(因为它是函数调用的参数,直接出现在类的主体中)。在生产环境中,编译后的类可能会被缓存一段时间,这取决于您运行应用程序的方式,从而导致错误的值被传递到您的验证中。
      猜你喜欢
      • 1970-01-01
      • 2010-10-15
      • 2011-04-05
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      相关资源
      最近更新 更多