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

zsl*_*ius 12 ruby ruby-on-rails

我有一个代码来检查红宝石中的零.所以我想要实现的是:例如,如果我打电话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
Run Code Online (Sandbox Code Playgroud)

更新:

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

严格与懒惰的评价

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

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

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

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

drh*_*ris 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)
Run Code Online (Sandbox Code Playgroud)

你的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)
Run Code Online (Sandbox Code Playgroud)

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

def get_score_value(value)
  (value or 0).round(2)
end
Run Code Online (Sandbox Code Playgroud)


Dig*_*oss 8

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

def f x
  yield if x
end

x = nil
f x do 
  x - 1
end
Run Code Online (Sandbox Code Playgroud)