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