From: fREW Date: 2007-06-02T06:23:27+09:00 Subject: Re: nested methods don't really exist?! On 6/1/07, 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(). > > T. > > > Once for a class I had to write a simple regular expression parser and I used some inner methods (w/closures) and it turned out to make the code a lot more simple. If you have to pass a variable to every method in a class, it might as well be a global. Similarly, if it's used in every inner method in a large method, you might as well use closures. In general it is probably overkill to have inner methods, but with complex code I found it pretty convenient. -- -fREW