From: Robert Klemme Date: 2008-03-08T00:07:22+09:00 Subject: Re: the value in ensure block is not returned 2008/3/6, Oliver Peng : > Robert Klemme wrote: > > On 06.03.2008 16:46, Oliver Peng wrote: > > >> irb(main):009:1> end > >> => nil > >> irb(main):010:0> test > >> => 2 > >> > >> I am expecting that 1 should be returned by is 2. > > > > Why should it? If you think about it you will see that it's actually > > good the way it is. The result of evaluating code in /ensure/ cannot be > > returned under all circumstances (see Gary's reply). And for normal > > execution of a block of code you want the result of the code block to be > > returned - not the result of /ensure/. The code in /ensure/ is intended > > to do some cleanup that has to occur under all circumstances but not > > interfere with normal processing. > > > >> So it is obviously that all codes in ensure block have been run. But the > >> return value is always the last value before ensure block. > > > > Yes, no problem here. > > > > Cheers > > > > robert > > > Ok. I see. > > I am also curious what will happen if I change the return value in > ensure block. Here is my test code: > > irb(main):003:0> def test > irb(main):004:1> begin > irb(main):005:2* a = 1 > irb(main):006:2> b =2 > irb(main):007:2> b > irb(main):008:2> ensure > irb(main):009:2* b += 3 > irb(main):010:2> end > irb(main):011:1> end > => nil > irb(main):012:0> test > => 2 > > It looks that the result value has been saved to a temp place before > running ensure block. Is that correct? The return value is determined the very moment the block ends, which means that the *reference* is saved (as always in Ruby). But since you used Fixnums and simply reassigned to b ("b += 3") this won't be visible. But irb(main):001:0> def t irb(main):002:1> s="foo" irb(main):003:1> ensure irb(main):004:1* s.replace "see?" irb(main):005:1> end => nil irb(main):006:0> t => "see?" irb(main):007:0> In other words, of course you can change the object before it is returned. > I also use global variable to test. > > irb(main):014:0> @@value = 0 > => 0 > irb(main):015:0> def test1 > irb(main):016:1> begin > irb(main):017:2* @@value = 3 > irb(main):018:2> ensure > irb(main):019:2* @@value = 8 > irb(main):020:2> end > irb(main):021:1> end > => nil > irb(main):023:0> test1 > => 3 > irb(main):024:0> @@value > => 8 Same story: you reassigned. Cheers robert -- use.inject do |as, often| as.you_can - without end