From: "Brett H. Williams" Date: 2003-08-22T03:06:57+09:00 Subject: Re: for/in loop On Aug 22, Paul Brannan wrote: > On Fri, Aug 22, 2003 at 02:14:15AM +0900, Mark J. Reed wrote: > > Do you have an explanation posted somewhere of why you feel block-local > > variables are evil? It seems cleaner to me to have variables go > > away at the end of the block when I don't need them anymore, than > > to have them hanging around and taking up memory until the whole method > > exits. > > If this is really a concern for you, it should probably be a sign that > the method is too long and needs to be broken down into many separate > methods, each with a distinct purpose. The pitfall of block local variables (they way Ruby works now)... There seems to be nothing wrong with: def action(foo) foo.each do |x| some_str = transform(x.some_attr.strip) puts "transformed some_attr for #{x}: #{some_str}" end # ... end It's nice to know that some_str is not polluting the variable namespace of the action() method. In practice it probably doesn't matter (if you assumed it was block local and used it elsewhere later in action(), it'd be reassigned anyhow). If it was used prior to the block, then it isn't block local under the current scheme. I guess it's impossible to have a situation where changing Ruby to get rid of block local variables would cause a problem with existing code. As far as why the current implicit lexical scoping scheme could be considered evil, consider this: def action(foo) some_str = some_method() foo.each { |x| some_str = ... } # I meant for some_str to be block local some_other_method(some_str) # oops! modified in the block! end I _think_ this why people say they are evil--because knowing that block local variables spring into existence (implicit scoping) can lead you to believe you are protected when sometimes you aren't. A couple of times I've accidentally done this (usually in the presence of cut and paste), and it can be a subtle bug to deal with. That's why breaking a method up would lessen the chances of this occurring, as you'd be less likely to see you'd used a variable in a block which already had scope in the method. Does that help? Or maybe I'm even missing something else evil? Is there something evil in general about block locals, even if they _aren't_ implicitly scoped? Because I think something that is explicitly stated to be block local obviously doesn't suffer from the above pitfall, and I can't see the problem with that. As to whether it's necessary though... Just my $.02 -- Brett Williams