Reputation: 2885
How can I print a message and then return from a function in ruby?
2.3.4 :038 > def foo(num)
2.3.4 :039?> print "Your number is: #{num}" && return if num > 10
2.3.4 :040?> print "Number too small"
2.3.4 :041?> end
=> :foo
2.3.4 :042 > foo(47)
=> nil
2.3.4 :043 > foo(7)
Number too small => nil
2.3.4 :044 >
When I called foo with 47
why didn't I got Your number is: 47
in output?
PS: This function can be written in other simpler ways also, I just wanted to express my doubt via this function.
Upvotes: 4
Views: 3140
Reputation: 7068
Since print
(and puts
) returns nil
, this works just as well:
def foo(num)
return print "Your number is: #{num}" if num > 10
print "Number too small"
end
And to show clearer intention, place the guard clause first:
def foo(num)
return print "Number too small" if num <= 10
print "Your number is: #{num}"
end
Examples:
> foo 47
Your number is: 47=> nil
> foo 7
Number too small=> nil
Upvotes: 3
Reputation: 106792
Because Ruby reads this line
print "Your number is: #{num}" && return if num > 10
like this
print("Your number is: #{num}" && return) if num > 10
That leads the method to return
before it had the chance to print
anything.
Adding a pair of parenthesis helps Ruby to resolve the desired order:
print("Your number is: #{num}") || return if num > 10
Upvotes: 6
Reputation: 114138
You have a precedence issue which can be fixed using parentheses. But since you are trying to express a control flow, you should use the control flow operators and
and or
instead of the boolean operators &&
and ||
.
The idiom works like this: (just examples, it's not limited to return
and fail
)
do_something and return "it worked"
or:
do_something or fail "it didn't work"
It allows you to evaluate a second expression depending on whether the first expression succeeded or not. do_something
is supposed to return a truthy value in case of success and a falsey value in case of failure.
print
however always returns nil
, so it doesn't work as expected in this regard. You would have to reverse the logic:
print "Your number is: #{num}" or return
But this doesn't read naturally any more, does it? Beside, return
is always invoked, because print
will never return a truthy value. You actually want:
print "Your number is: #{num}"
return
I would therefore simply write:
def foo(num)
if num > 10
puts "Your number is: #{num}"
else
puts "Number too small"
end
end
Upvotes: 4
Reputation: 478
One more way to do one line if statements is with ;
def foo(num)
if num < 10; print "Your number is: #{num}" && return; end
print "Number too small"
end
Upvotes: 1
Reputation: 121000
Just out of curiosity:
def foo(num)
print case num
when -Float::INFINITY...10 then "Number too small"
else "Your number is: #{num}"
end
end
Upvotes: 1
Reputation: 3398
def foo(num)
puts(num > 10 ? "Your number is: #{num}" : "Number too small")
end
I think this is the cleaner way to do that, with an If ternary. Hope this helps
Upvotes: 3