From: Kevin Bullock Date: 2004-12-03T15:43:26+09:00 Subject: Re: nested defs, what if... On Dec 2, 2004, at 5:20 PM, trans. (T. Onoma) wrote: > Well, it's an idea, but I don't think a very good one. In general I > don't > think this is useful, and would rather obfuscate code if actually > used. I > think what would be more useful is if such methods were local methods, > like > local variables: > > class A > def a > def b(x) > x + 1 > end > 10.times{ |i| print b(i) } > end > end > > o = A.new > o.b => NoMethodError > A.a => 12345678910 > o.b => NoMethodError > > This would allow for embedded subroutines --much more useful. This would also make Ruby more like LISP, which allows any depth of inner functions to be defined. Those inner functions are only in scope in the defining function. Ruby's blocks function this way right now, actually. That is, to achieve the above effect, you could do: class A def a b = proc do |x| x + 1 end 10.times { |i| print b.call(i) } end end o = A.new ==># o.b NoMethodError: undefined method `b' for # from (irb):10 o.a 12345678910 ==>10 o.b NoMethodError: undefined method `b' for # from (irb):13 In this example, b is a reference to a block, rather than a method, and b is only in scope within a(). Embedded subroutines can indeed be useful, especially in recursive methods that use an "interface method" and a "worker method" that takes extra parameters. For example: def fact( n ) def fact_iter( n, total ) if n == 1 total else fact_iter( n - 1, total * n ) end end fact_iter( n, 1 ) end fact( 3 ) ==> 6 In this case, fact_iter() doesn't need to be visible to the outside world; but the way Ruby currently works, the following can happen: fact_iter( 3 ) ==> 6 The question becomes, though, whether or not fact_iter() is being defined every time fact() is called. It shouldn't be hard to optimize around this redefinition problem. (Does Ruby already do so?) Pacem in terris / Mir / Shanti / Salaam / Heiwa Kevin R. Bullock