Ruby on rails 如何对Ruby参数进行惰性求值
我有一个在ruby中检查nil的代码。因此,我想要实现的是: 例如,如果我调用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
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"