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
==>#<A:0x49708>
o.b
NoMethodError: undefined method `b' for #<A:0x49708>
from (irb):10
o.a
12345678910 ==>10
o.b
NoMethodError: undefined method `b' for #<A:0x49708>
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
···
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.