From: Brian Candler Date: 2003-02-13T08:11:53+09:00 Subject: Re: Lexical scope and closures On Wed, Feb 12, 2003 at 01:21:40PM +0900, Patrick Logan wrote: > I read recently a flaw I did not previously know about... > > "Blocks (closures) in Ruby do not introduce a new scope, only methods > do. It's not actually true. Blocks do introduce a new scope, iff the variable name has not been used already. So # no previous use of 'x' [1,2,3].each{|x| print x} creates a local instance of 'x' for each time the block executes. This is an important distinction where the block is being run as a thread, or is recursive. > This is generally acknowledged as a flaw by the Ruby community but is > left > in for backwards compatibility. For example: > > x = 0 > [1,2,3].each{|x| print x} > #x now equals 3" Matz is thinking of changing the behaviour for a future version of Ruby as follows: (1) block parameters are always locally scoped (so '|x|' in that example will behave as if the outside 'x' did not exist, although a warning will be printed because of the re-use of the name; but x will still be 0 after the iterator has finished) (2) variables introduced _within_ a block are always scoped to the entire method, not the block. e.g. [1,2,3].each{|x| j = x} will behave the same as j = nil [1,2,3].each{|x| j = x} and hence the value of j will persist after the iterator terminates. (3) some other syntax will be introduced for cases where you really need j to be a block-local variable (e.g. if this block calls itself recursively or is a thread). This might be something like: [1,2,3].each{|x| local { |j| j = x } } This has been discussed at great length :-) Regards, Brian.