The difference between Ruby's implicit “value of a block” and its explicit “return from a method with a value” is best illustrated by example.
def foo puts 'a' 0 ensure puts 'b' 1 end irb(main):001:0> foo a b => 0 def bar puts 'a' return 0 ensure puts 'b' return 1 end irb(main):002:0> bar a b => 1
The explicit return statement literally means “stop the method right now, and use this return value”, whereas in uninterrupted flow the ensure sub-block's final value is superseded by the method's.
The gotcha happens thus:
def baz puts 'a' raise 'fail' ensure puts 'b' 1 end irb(main):003:0> baz a b RuntimeError: fail from (irb):19:in `baz' from (irb):34 from /usr/bin/irb1.9.1:12:in `<main>' def freb puts 'a' raise 'fail' ensure puts 'b' return 1 end irb(main):004:0> freb a b => 1
The same thing happened in Ruby 1.8 – it's a language feature. This is partly why I don't use return statements, except when I really want to be explicit about breaking the flow.