Reputation: 11887
In venturing into Ruby, I started toying with things like the way Ruby returns the last thing you've mentioned even if it was not after a return
construct. However, why don't these two snippets work the same way? Shouldn't they?
module Enumerable
def palindrome?
reversed_self = self.reverse
self.each_with_index {|el,index|
unless self[index]==reversed_self[index]
return false ## <-----
end
}
true
end
end
all good so far: puts ['foo','bar','baz'].palindrome? prints 'false'
and
module Enumerable
def palindrome?
reversed_self = self.reverse
self.each_with_index {|el,index|
unless self[index]==reversed_self[index]
false ## <------
end
}
true
end
end
puts ['foo','bar','baz'].palindrome? prints 'true' for some reason
What's the science behind this?
Upvotes: 2
Views: 252
Reputation: 118681
Not quite! A return
from inside a block is different from a return
inside a lambda, as mentioned in my answer here. When you return
from inside a block, you're returning from the entire method rather than just the block.
We can illustrate this as follows:
return :foo # => LocalJumpError: unexpected return
[1, 2, 3].map { return :foo } # => LocalJumpError: unexpected return
[1, 2, 3].map { :foo } # => [:foo, :foo, :foo]
Normally, this doesn't happen with lambdas:
l = lambda { return :foo }
l.call # => :foo
[1, 2, 3].map { l.call } # => [:foo, :foo, :foo]
But when we try to pass the lambda as a block to the method, the behavior changes back:
[1, 2, 3].map &l # => LocalJumpError: unexpected return
Upvotes: 2
Reputation: 132862
Ruby will return the value of the last executed expression in a method. The false
in the second version is not the last expression, there's nothing telling Ruby to stop executing at that point so it will chug along until the method ends.
return
is a way to explicitly say to Ruby to stop executing and return a value.
Upvotes: 3
Reputation: 230346
If no return
statement is present, then return value of a function is the last value evaluated. In the second snipped the last value is always true
.
First snippet returns early with false
. Second does nothing with that false
, it's discarded.
Upvotes: 1