On Thu, Jan 30, 2003 at 04:48:04AM +0900, ahoward wrote:
>   result =
>     if callback
>       callback (*args)
>     else
>       default_callback (*args)
>     end
> 
> or more generally
> 
>   object and object.method
> 
> the ol 'call a method on object if object is not nil'

Yes, but a variable going out of scope is not the same as a variable being
in scope with value nil. For example:

[1,2,3].each do |foo|
  myvar = foo
end

myvar and puts myvar

==> NameError: undefined local variable or method `myvar' for #<Object:0x810dcd8>

So your example doesn't work in this case anyway; you would have to say

defined? object and object.method

The proposed new behaviour is that myvar persists beyond the loop, whereas
now it doesn't (if it didn't exist before the loop). I can't see how that
would break things. You would have to write pretty obscure code for it to
work where 'myvar' does not exist, but break if 'myvar' does exist :-)

FWIW, I think the proposed solution looks like one of those "doh! why-
didn't-we-think-of-it before" ones. At least, anything to avoid the
nightmare of two different assignment operators with different semantics!!

Aside: I'd still prefer block parameters to be properly local, because I'll
still end up using stupid names like

myobject.thing { |local_i, local_j|  ... use local_i,local_j ... }

to try to ensure that accidental clashes with 'i' and 'j' are avoided. It
seems to me that these are really formal parameters to the block. If I can
write

def myproc(i)
  ... use formal i
end

and know that myproc won't clobber any existing local i in scope at the
time, why not the same for blocks? Apart from the fact that it's not
backwards-compatible, of course.

But having said that, I know I don't understand the scope rules anyway,
because

i=10
def myproc()
  puts i
end
myproc

doesn't do what I expect it to do.

Regards,

Brian.