class A
def numbers
[1,2,3,4]
end
def get_numbers(condition)
numbers = [3,5] if condition
numbers
end
end
a = A.new
a.get_numbers(true) # [3,5]
a.get_numbers(false) # nil
I expect it to return [1,2,3,4]
in the second case !
P.S. I am not looking for a solution(I can just have two different variable names to solve my issue), rather I am looking for an explanation for this behaviour, Does ruby creates the variable numbers
during runtime itself & initializes to nil
because of the if
condition ?
@sawa has the answer, but I'd recommend a little different change to the code. I'd go from:
To:
I like to keep it simple and have the code obvious. The assignment to the local variable accomplishes nothing and using method names without the empty parenthesis is confusing/hides that it's a method call.
An alternate way to write the code, that is entirely acceptable, is:
or even:
Writing code is all about getting the right answer, but also about being able to return to it in six months or a year and not needing to spend hours trying to remember what you did, or worse, WHY you did it. Other people inherit our code so we need to be sensitive to the destruction we can cause in their minds when we don't write clearly, cleanly and concisely.
When a token can be interpreted as either a local variable or a method call, local variable has priority. The last
numbers
in the method definition is interpreted as a local variable. To make it interpreted as a method call, you need to make it unambiguous.This is probably what you intended:
But this is very smelly code, and it should be like this:
numbers
during runtime itself & [and] initializes [initialize it] tonil
because of theif
condition?Yes. Whether or not the condition is satisfied, Ruby will parse everything, and if a local variable is not assigned because the condition is not satisfied, it will be initialized to
nil
.