On 6/1/07, Trans <transfire@gmail.com> wrote:
>
>
> On Jun 1, 3:45 pm, Robert Klemme <shortcut...@googlemail.com> 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
> > => #<Foo:0x7ff87288>
> > 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