Ruby-on-rails – How to do lazy evaluation of Ruby arguments

rubyruby-on-rails

I have a code to do a check of nil in ruby. So what I want to achieve is this:
for example, if I call get_score_value(nil,(nil-1)). I want ruby to delay the evaluation of nil-1 till it reaches the get_score_value function, instead of evaluate it before it got passed in the function. In another word, I want to pass a mathematical expression as an argument into a method.
What is the most elegant way to do this in ruby? Thanks very much

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

UPDATE:

I just realized this question is actually related to the topic of lazy and strict evaluation. ( the following is from this great site:
http://www.khelll.com/blog/ruby/ruby-and-functional-programming/

Strict versus lazy evaluation

Strict evaluation always fully evaluates function arguments before invoking the function. Lazy evaluation does not evaluate function arguments unless their values are required to be evaluated. One use of Lazy evaluation is the performance increases due to avoiding unnecessary calculations.

However as the following example shows, Ruby use Strict evaluation strategy:

print length([2+1, 3*2, 1/0, 5-4])
=>ZeroDivisionError: divided by 0

The third parameter of the passed array contains a division by zero operation and as Ruby is doing strict evaluation, the above snippet of code will raise an exception.

Best Answer

You might be interested in using a 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)

Your proc is like a normal method, it can still test for nil and things like that.

Or, it allows you to provide separate functions to handle those situations:

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)

Also note the potential use of the or keyword in cases when you simply want to convert it to an empty or default type of the input (i.e. use 0 for numbers, [] for arrays, etc.)

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