On May 25, 2004, at 12:13 PM, Florian Gross wrote:
> Minero Aoki wrote:
>
>> Hi all,
>
> Moin!
>
>> * Allows Proc#call to take a block.
>> def m(&block)
>> block.call { p "OK" }
>> end
>> m {|&b| b.call } #=> "OK"
>
> Yay, finally we'll be able to use define_method() everywhere where we
> would use def instead.
>
> However all this raises some questions:
>
> 1) What will yield(*[]) do?
I would assume the same as currently: it expands to zero arguments,
becomes yield()
> 2) What will happen with these examples?
>
> define_method(:foo) { |arg| result = arg }
> foo(5); result # => 5 or ~> NameError?
>
> # Or more interesting:
> define_method(:foo) { foo = nil; return true }
> foo # => true or nil or NameError?
> foo # => true or nil?
IIUC, the first snippet would give a NameError, the second would return
true twice. That's the way it is now...
Why would rescoping rules be changed? Currently, when you call
define_method, Class.new, Module.new, etc., the block is rescoped (is
that the right word?) and local variables never leak in. So, assuming
they don't make a silly change, define_method would be _exactly_
orthogonal to def...end:
define_method(:foo){|a,b,*c,&d| a + d[c] + b}
def foo(a,b,*c,&d) a + d[c] + b end
>
> 3) What will happen with these examples?
>
> [1, 2, 3].each do |item|
> [1, 2, 3].each do |item|
> # Exception or reassignment of outer item or
> # own private inner item?
> end
> end
It looks like an exception, from the explanation. I'm not too excited
about that, but I guess it could help protect you from logic errors.
> [1, 2, 3].each do |item|
> [1, 2, 3].each do |inner_item|
> item += 1 if item == inner_item
> end
> p item
> end
I think this would work like you expect, since only block parameters
are private to inside the block. the item += 1 part should leak out to
the surrounding block.
Disclaimer: This is only based on the way I read it; I could very
likely be all wet. :)
cheers,
Mark