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

Ruby on rails 如何对Ruby参数进行惰性求值,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个在ruby中检查nil的代码。因此,我想要实现的是: 例如,如果我调用get\u score\u value(nil,(nil-1))。我希望ruby延迟对nil-1的求值,直到它到达get\u score\u value函数,而不是在函数中通过之前对其求值。换句话说,我想把一个数学表达式作为参数传递给一个方法。 在ruby中,最优雅的方法是什么?非常感谢 def get_score_value(value,value2) value.nil? ? "NULL" : value2

我有一个在ruby中检查nil的代码。因此,我想要实现的是: 例如,如果我调用
get\u score\u value(nil,(nil-1))
。我希望ruby延迟对
nil-1
的求值,直到它到达
get\u score\u value
函数,而不是在函数中通过之前对其求值。换句话说,我想把一个数学表达式作为参数传递给一个方法。 在ruby中,最优雅的方法是什么?非常感谢

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

我刚刚意识到这个问题实际上与懒惰和严格评估的话题有关。(以下是来自这个伟大的网站:

严格评估与懒惰评估

严格求值总是在调用函数之前对函数参数进行完全求值。除非需要对函数参数的值进行求值,否则惰性求值不会对函数参数进行求值。惰性求值的一个用途是避免不必要的计算,从而提高性能

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

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

传递数组的第三个参数包含一个除法为零的操作,由于Ruby正在进行严格的求值,上面的代码片段将引发一个异常


您可能对使用进程感兴趣

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)
还请注意,如果您只想将
关键字转换为空的或默认的输入类型(即使用0表示数字,[]表示数组等),则可能会使用该关键字


Ruby-ish实现这一点的方法是将表达式放在方法的块中,并让方法执行条件产出

def f x
  yield if x
end

x = nil
f x do 
  x - 1
end
可以使用块:

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"

这真的很复杂;他可以把表达式放在一个块中,
if
语句围绕着
产生。
是的,这有点复杂,但这确实取决于他在寻找什么。他问我是否要将表达式作为参数传递,从而传递lambda/proc,所以我就这样做了。我正要添加第三个选项of使用块,但我看到你这么做了。因此,他现在有3个很好的选择,这取决于他真正需要什么。你的解决方案确实具有在几乎任何语言中工作的优势,而使用块只能在Ruby和Smalltalk中工作。:-)这是称为惰性评估还是其他什么?它可以被视为惰性评估的一种形式,因为您可以将表达式的执行延迟到需要之前。但是,它实际上只是一个函数指针或lambda。惰性评估往往意味着它在堆栈上一直都是惰性的。我想在我的回答中这样做,但看起来有点混乱。你去掉了括号,一开始读起来有点困难,但是,是的,这看起来是真的
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"