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