如何对Ruby参数进行惰性求值

时间:2011-08-11 19:37:00

标签: ruby-on-rails ruby

我有一个代码来检查ruby中的nil。所以我想要实现的是: 例如,如果我拨打get_score_value(nil,(nil-1))。我希望ruby延迟nil-1的评估,直到它到达get_score_value函数,而不是在函数传递之前对其进行求值。换句话说,我想将数学表达式作为参数传递给方法。 在ruby中最优雅的方法是什么?非常感谢

def get_score_value(value,value2)
    value.nil? ? "NULL" : value2.round(2)
end

更新:

我刚刚意识到这个问题实际上与懒惰和严格评估的主题有关。 (以下是来自这个伟大的网站: http://www.khelll.com/blog/ruby/ruby-and-functional-programming/

  

严格与懒惰的评估

     
    

严格评估始终在调用函数之前完全评估函数参数。延迟评估不会评估函数参数,除非需要评估它们的值。懒惰评估的一个用途是由于避免不必要的计算而导致性能提高。

         

但是,如下例所示,Ruby使用严格的评估策略:

         

打印长度([2 + 1,3 * 2,1 / 0,5-4])     => ZeroDivisionError:除以0

         

传递数组的第三个参数包含除零操作,并且由于Ruby正在进行严格评估,上面的代码片段将引发异常。

  

3 个答案:

答案 0 :(得分:24)

您可能对使用Proc ...

感兴趣
func = Proc.new {|n| n -1 }

def get_score_value(value, proc)
  if value.nil?
    return proc.call(0)
  end
end

p get_score_value(nil, func)

你的proc就像一个普通的方法,它仍然可以测试nil和类似的东西。

或者,它允许您提供单独的功能来处理这些情况:

func1 = Proc.new {|n| n -1 }
func2 = Proc.new { "was nil" }

def check_for_nil(value, funcNil, funcNotNil)
  if value.nil?
    return funcNil.call()
  else
    return funcNotNil.call(value)
  end
end

p check_for_nil(nil, func2, func1)
p check_for_nil(1, func2, func1)

另请注意,当您只想将其转换为空或默认类型的输入时,可能会使用or关键字(例如,对数字使用0,对数组使用[]等)< / p>

def get_score_value(value)
  (value or 0).round(2)
end

答案 1 :(得分:8)

Ruby-ish这样做的方法是将表达式放在方法的块中,让方法执行条件yield。

def f x
  yield if x
end

x = nil
f x do 
  x - 1
end

答案 2 :(得分:2)

您可以使用块:

def get_score_value value
  value.nil? ? "NULL" : yield
end

x = 1
puts get_score_value(x) { x-1 }  #=> 0

x = nil
puts get_score_value(x) { x-1 }  #=> "NULL"