From: Robert Klemme Date: 2007-06-02T17:55:21+09:00 Subject: Re: nested methods don't really exist?! On 01.06.2007 23:14, Trans wrote: > > On Jun 1, 3:45 pm, Robert Klemme wrote: >> On 01.06.2007 14:36, Artur Merke wrote: >> >> >> >>> Hi, >>> I've just encountered somehow strange (for me) behavior of nested >>> methods in ruby: >>> class A >>> def a >>> def b >>> print "bbb" >>> end >>> end >>> def c >>> b >>> end >>> end >>> irb(main):013:0> A.new.c >>> bbb=> nil >>> class A >>> def b >>> print "BBB" >>> end >>> end >>> irb(main):019:0> A.new.c >>> BBB=> nil >>> my first thought was that method/function 'b' would be local to >>> method 'a' in class A (like it would be in Pascal). But this is of >>> course not >>> the case, as the above example shows. >>> Is suppose that method 'a' (re)defines method 'b' every time it is >>> called, therefore using nested methods doesn't seem to be a >>> good idea in ruby (better readability but much worse performance, esp. >>> when 'b' isn't a oneliner) >>> any comments? >> You're right on. I think that nested methods are a bad thing to have >> especially since invocation of an instance method has side effects on >> all instances: >> >> irb(main):001:0> class Foo >> irb(main):002:1> def a >> irb(main):003:2> def b; 1; end >> irb(main):004:2> 2 >> irb(main):005:2> end >> irb(main):006:1> end >> => nil >> irb(main):007:0> f=Foo.new >> => # >> irb(main):008:0> f.b rescue "no" >> => "no" >> irb(main):009:0> f.a >> => 2 >> irb(main):010:0> f.b rescue "no" >> => 1 >> irb(main):011:0> >> irb(main):012:0* Foo.new.b rescue "no" >> => 1 >> irb(main):013:0> >> >> #b is defined only after #a has been invoked at least once. I cannot >> think of a scenario where you would want this behavior. > > There are dynamic behavior scenarios such as memoize where it could be > used. But such cases are pretty rare. So I agree. Unless inner defs > are local to their outer def, akin to local variables, they really > aren't very useful --being little more than a shortcut for (class << > self; self; end).define_method(). That's exactly what they are not. If at all they are a shortcut for self.class.define_method(), i.e. methods defined that way a regular instance methods. I also think that for memoize and such other mechanisms are far more useful than current Ruby nested methods. Actually the current state of affairs is a queer mix, because the definition is nested but the scope is not (they are neither restricted to the current instance nor to the current method). Maybe that is the major reason for them not being too useful. Kind regards robert