From: Robert Klemme Date: 2006-01-04T19:12:58+09:00 Subject: Re: block and method local variables Daniel Sch�le wrote: > if I change line 566 to > irb(main):566:0> xxx {|x| x=[2] } > than it would not work Note, that you can use get the return value of the block from yield: def foo p yield( 111 ) end >> foo {|x| x + 10} 121 => nil > the reason I came accross this is following > I was reading > > " > Parameters to a block may be existing local variables; if so, the new > value of the variable will be retained after the block completes. This > may lead to unexpected behavior, but there is also a performance gain > to be had by using variables that already exist > " > and in my understanding all variables defined in a method > are "local" (C++ background) > > If not local what are they considered to be then? They are local. Stress in the setence above must be on "existing". It means a situation like this: def get_last(enum) last = nil enum.each {|last|} last end >> get_last [1,2,43,3,2,4] => 4 This works because "last" is defined before the block. This does not work: def get_last(enum) enum.each {|last|} last end >> get_last [1,2,43,3,2,4] NameError: undefined local variable or method `last' for main:Object from (irb):26:in `get_last' from (irb):28 from :0 IOW, if the variable is defined in the surrounding scope that is the one used. If it's defined only in the block (either as parameter or in the body) it's visibility is limited to the block. Note that this is how most PL do nested scoping. /* C */ int foo() { int x; { /* x is visible here */ int y = x; } /* no y visible here */ } Note, that the scope of block parameters may change in the future. There have been lengthy discussions about this but ATM I don't remember the details. Kind regards robert