Let’s say I have a function
def odd_or_even n
if n%2 == 0
return :even
else
return :odd
end
end
And I had a simple enumerable array
simple = [1,2,3,4,5]
And I ran it through map, with my function, using a do-end block:
simple.map do
|n| odd_or_even(n)
end
# => [:odd,:even,:odd,:even,:odd]
How could I do this without, say, defining the function in the first place? For example,
# does not work
simple.map do |n|
if n%2 == 0
return :even
else
return :odd
end
end
# Desired result:
# => [:odd,:even,:odd,:even,:odd]
is not valid ruby, and the compiler gets mad at me for even thinking about it. But how would I implement an equivalent sort of thing, that works?
edit
In reality, the solution to my problem matters to me a lot less than the motivation/reasoning behind it, to help me understand more how ruby blocks work 🙂
You’re so close. Just remove the
returns and you’re golden.This is because the block passed to
mapis a proc (i.e. created withProc.new), and not a lambda. Areturnwithin a proc doesn’t just jump out of the proc- it jumps out of the method that executed (i.e. calledcallon) the proc. A return within a lambda, on the other hand, jumps out of only the lambda.The
procmethod returns a lambda in Ruby 1.8, and a Proc in Ruby 1.9. It’s probably best to just not use this method and be explicit with which construct you want to use.I’m guessing you were either in IRB or a plain ruby script when you were trying this out.
The lesson to learn from this is to use implicit returns unless you can’t, I guess.