Nested methods don't really exist?!

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?

I am not exactly a wizard, but I think that your issue is context.
You are trying to call methods that only exist in other methods. This
should not be! You have to either define it outside of the method and
then pass it in (or reference it inside) or redefine it. Does that
help at all?

···

On 6/1/07, Artur Merke <am@artbot.de> 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?

--
-fREW

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.

Kind regards

  robert

···

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?

Yes this would re-define the method b() on each invocation of a() at
the class level.
Depending upon what you actually want, there may be different options
in Ruby, but you can use this "redefinition" nicely if you create a
singleton method of the same name as the enclosing method to get
interesting possibilities. (which is not exactly re-definition btw...)

One such use case is discussed on my blog -
   Nasir's blog on software, design and trends: Calculate once Cache forever

- nasir

···

On 6/1/07, Artur Merke <am@artbot.de> 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?

Hi --

···

On Fri, 1 Jun 2007, 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

I get:

   inner.rb:9:in `c': undefined local variable or method `b' for
   #<A:0x1ea244> (NameError) from inner.rb:13

with Ruby 1.8.6, because b doesn't get defined until a is called.

Can you reproduce exactly what you're doing, including Ruby version?

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

What fREW said. Show me a language that actually allows you to do this and
I'll show you a language that is the definition of scoping issues.

You've defined method #b *inside* of method #a, so it should only be
callable when in method #a.

Jason

···

On 6/1/07, fREW <frioux@gmail.com> wrote:

On 6/1/07, Artur Merke <am@artbot.de> 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?
>

I am not exactly a wizard, but I think that your issue is context.
You are trying to call methods that only exist in other methods. This
should not be! You have to either define it outside of the method and
then pass it in (or reference it inside) or redefine it. Does that
help at all?

--
-fREW

FWIW, nested subs in Perl cause horrendous problems. For the gory details,
see mod_perl: Perl Reference

This should be enough to put you off mod_perl for life :slight_smile:

Regards,

Brian.

···

On Sat, Jun 02, 2007 at 04:45:20AM +0900, Robert Klemme wrote:

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:

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.

···

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.

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.

···

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.

--
-fREW

>
> > 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:

...

>
> #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,

Trans, you lost me there on several counts.

What would it mean for an inner def to be local to an inner def.

I get the idea that you mean that, in analogy to local variables we'd see this:

class A

   def outer
       def inner
           ...
       end
       inner # this should work here as should
       self.inner # but what about
       class.new.inner # should inner be an instance or singleton method?
       another rescue "Oops"
       method(:inner)
   end

   private
   def another
      inner # raises NoMethodError even when called from outer
   end
end

A.new.inner.call # And should this work?

So I think the basic meaning is that the inner method would only live
during the execution of the outer method, and would be inaccessible
outside of that stack frame, except maybe if they were returned or
passed.

Of course these all sound like use cases which could easily be handled
with a proc and slighly different syntax.

they really aren't very useful --being little more than a shortcut for
(class << self; self; end).define_method().

Of course this wouldn't work since define_method is private.

Now as Robert K, points out what really happens is that the inner def
is "executed" whenever the outer method is, and other than the timing
it does the same thing as if it were in the class/module context.

Now if one wanted to avoid re-defining such inner methods, one could
write something like:

class A
    def outer
        unless self.class.instance_methods(false).include?(:inner)
            def inner
                 "inner: a regular instance method"
            end
       end
        unless singleton_methods(false).include?(:my_inner)
            def self.my_inner
                 "my_inner: a singleton instance method"
            end
       end
    end
end

Just anothe way of doing dynamic method definition.

Of course you'd need to do something like carefully remove_method'ing
those inner methods if you wanted to change them.

···

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:

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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

···

On 01.06.2007 23:14, Trans 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().

Trans wrote:

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().

Early on, SICP shows the use of inner methods for abstracting function behavior but Ruby does not afford the same scoping.

···

--
James Britt

"Simplicity of the language is not what matters, but
simplicity of use."
  - Richard A. O'Keefe in squeak-dev mailing list

Trans, you lost me there on several counts.

What would it mean for an inner def to be local to an inner def.

I get the idea that you mean that, in analogy to local variables we'd see this:

class A

   def outer
       def inner
           ...
       end
       inner # this should work here as should
       self.inner # but what about
       class.new.inner # should inner be an instance or singleton method?
       another rescue "Oops"
       method(:inner)
   end

   private
   def another
      inner # raises NoMethodError even when called from outer
   end
end

A.new.inner.call # And should this work?

So I think the basic meaning is that the inner method would only live
during the execution of the outer method, and would be inaccessible
outside of that stack frame, except maybe if they were returned or
passed.

Of course these all sound like use cases which could easily be handled
with a proc and slighly different syntax.

Right. Inner def would be treated just like local variables. There
would be no instance access, private or public. They would be very
much like procs. But procs differ in a couple of ways, most notably in
that they have a different call syntax. With local methods one could
do:

  class X
    def a
      "foo"
    end
    def b
      def a
        "bar"
      end
      a
    end
  end

  X.new.b => "bar"

The point being that the local method can serve in place of the
instance methods without subsequent syntax changes to the call --
something lambdas don't allow (ie. the call to #a would have to be
changed to a.call or a instead).

> they really aren't very useful --being little more than a shortcut for
> (class << self; self; end).define_method().

Of course this wouldn't work since define_method is private.

Common mistake on my part. Making #define_method public is not beyond
me :wink: But I am wrong about the shortcut. I thought the inner defs were
creating singleton methods. I'm a bit startled to see they are
defining instance methods, and pinned to the module/class in which the
outer method is defined --not self.class. (Try it with a module to see
what I mean.) Inner defs are a rather new feature AFAIK, I wonder how
that decision was arrived at? Is there some reason for this, or is it
just a stop gag measure toward the eventual behavior in Ruby 2.0?

Now as Robert K, points out what really happens is that the inner def
is "executed" whenever the outer method is, and other than the timing
it does the same thing as if it were in the class/module context.

Now if one wanted to avoid re-defining such inner methods, one could
write something like:

class A
    def outer
        unless self.class.instance_methods(false).include?(:inner)
            def inner
                 "inner: a regular instance method"
            end
       end
        unless singleton_methods(false).include?(:my_inner)
            def self.my_inner
                 "my_inner: a singleton instance method"
            end
       end
    end
end

Could. Though the would not work if the method were defined in an
included module.

T.

···

On Jun 1, 6:57 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:

>> #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).

Robert I think they are:
# vim: sts=2 sw=2 expandtab nu tw=0:

class A
  def a
    def b
      42
    end
  end

end

p A.new.methods.grep(/^b$/)
A.new.b

nested.rb:13: undefined method `b' for #<A:0xb7e337a0> (NoMethodError)

Did you overlook David's post?
I get exactly the same behavior than he does on a 1.8.5 Zenwalk
I have the impression that OP got the victim of a "leftover" in his irb session.

Cheers
Robert

Maybe that is the major reason for them not being too

···

On 6/2/07, Robert Klemme <shortcutter@googlemail.com> wrote:

useful.

Kind regards

        robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

It was a conscious choice on my part to using instance_methods(false)
for the instance method. This allows overriding with a new method, but
not redefining it the second time. If you wanted to not override then
you could use just instance_methods with the default true parameter
which returns methods from superclasses and included modules also.

It's a matter of what you are trying to do. There are other techniques
for determining the current state, like using defined?, with different
variations and edge cases.

···

On 6/2/07, Trans <transfire@gmail.com> wrote:

On Jun 1, 6:57 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:

> Now if one wanted to avoid re-defining such inner methods, one could
> write something like:
>
> class A
> def outer
> unless self.class.instance_methods(false).include?(:inner)
> def inner
> "inner: a regular instance method"
> end
> end
> unless singleton_methods(false).include?(:my_inner)
> def self.my_inner
> "my_inner: a singleton instance method"
> end
> end
> end
> end

Could. Though the would not work if the method were defined in an
included module.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Perhaps the OP was, but I think that Robert's statements are still correct:

$ cat innerdef.rb
class A
  def a
    def b
      42
    end
  end
end

puts "Using #{RUBY_VERSION}"
a = A.new
puts "Before invocation of a"
p a.methods & %w{a b}
p A.instance_methods(false)
a.a
puts "After invocation of a"
p a.methods & %w{a b}
p A.new.methods & %w{a b}
p A.instance_methods(false)

$ ruby innerdef.rb
Using 1.8.5
Before invocation of a
["a"]
After invocation of a
["a", "b"]

···

On 6/2/07, Robert Dober <robert.dober@gmail.com> wrote:

On 6/2/07, Robert Klemme <shortcutter@googlemail.com> wrote:
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).

Robert I think they are:
# vim: sts=2 sw=2 expandtab nu tw=0:

class A
  def a
    def b
      42
    end
  end

end

p A.new.methods.grep(/^b$/)
A.new.b

nested.rb:13: undefined method `b' for #<A:0xb7e337a0> (NoMethodError)

Did you overlook David's post?
I get exactly the same behavior than he does on a 1.8.5 Zenwalk
I have the impression that OP got the victim of a "leftover" in his irb
session.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Ah, so inner defs won't be allowed after all. Figures, I guess. Why
have useful syntax when you can throw an error? :confused:

To be honest, I'm not sure I understand Ruby's vision for the future
these days. Why isn't Ruby further embracing the dynamic revolution
it's helped ignite? For example, why aren't we seeing 'def' become a
method, just like 'new' already is? I guess maybe the innovation is
over and Matz is settling into performance matters only.

T.

···

On Jun 2, 7:55 am, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/2/07, Robert Klemme <shortcut...@googlemail.com> wrote:

> >> #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).

Robert I think they are:
# vim: sts=2 sw=2 expandtab nu tw=0:

class A
  def a
    def b
      42
    end
  end

end

p A.new.methods.grep(/^b$/)
A.new.b

nested.rb:13: undefined method `b' for #<A:0xb7e337a0> (NoMethodError)

Did you overlook David's post?
I get exactly the same behavior than he does on a 1.8.5 Zenwalk
I have the impression that OP got the victim of a "leftover" in his irb session.

Cheers
Robert

Maybe that is the major reason for them not being too

> useful.

> Kind regards

> robert

Hi --

···

On Sat, 2 Jun 2007, Trans wrote:

On Jun 2, 7:55 am, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/2/07, Robert Klemme <shortcut...@googlemail.com> wrote:

#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).

Robert I think they are:
# vim: sts=2 sw=2 expandtab nu tw=0:

class A
  def a
    def b
      42
    end
  end

end

p A.new.methods.grep(/^b$/)
A.new.b

nested.rb:13: undefined method `b' for #<A:0xb7e337a0> (NoMethodError)

Did you overlook David's post?
I get exactly the same behavior than he does on a 1.8.5 Zenwalk
I have the impression that OP got the victim of a "leftover" in his irb session.

Cheers
Robert

Maybe that is the major reason for them not being too

useful.

Kind regards

        robert

Ah, so inner defs won't be allowed after all. Figures, I guess. Why
have useful syntax when you can throw an error? :confused:

They're allowed; they're just not executed until the enclosing method
is executed.

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Oh, I wasn't saying anything about your code. It's fine. I was just
further pointing out the slightly odd behavior that one might not
expect (I know I didn't), when using a module instead of a class.
Here's an example:

  module N
    def a
      def b
        "foo"
      end
    end
  end

  class X
    include N
  end

  X.new.a

  N.instance_methods(false) #=> ["a", "b"]

Notice #b isn't defined in X.

T.

···

On Jun 2, 8:05 am, "Rick DeNatale" <rick.denat...@gmail.com> wrote:

On 6/2/07, Trans <transf...@gmail.com> wrote:

> On Jun 1, 6:57 pm, "Rick DeNatale" <rick.denat...@gmail.com> wrote:
> > Now if one wanted to avoid re-defining such inner methods, one could
> > write something like:

> > class A
> > def outer
> > unless self.class.instance_methods(false).include?(:inner)
> > def inner
> > "inner: a regular instance method"
> > end
> > end
> > unless singleton_methods(false).include?(:my_inner)
> > def self.my_inner
> > "my_inner: a singleton instance method"
> > end
> > end
> > end
> > end

> Could. Though the would not work if the method were defined in an
> included module.

It was a conscious choice on my part to using instance_methods(false)
for the instance method. This allows overriding with a new method, but
not redefining it the second time. If you wanted to not override then
you could use just instance_methods with the default true parameter
which returns methods from superclasses and included modules also.

It's a matter of what you are trying to do. There are other techniques
for determining the current state, like using defined?, with different
variations and edge cases.

Sure was, sure was, I am just with you right now, thanks to your
explanation Rick.
I mean Robert's as emphasized by Rick, just gotta reread the whole
thread, now that I know what you are talking about :frowning:

Thx a lot to both of you.

Robert

···

On 6/2/07, Rick DeNatale <rick.denatale@gmail.com> wrote:

On 6/2/07, Robert Dober <robert.dober@gmail.com> wrote:
> On 6/2/07, Robert Klemme <shortcutter@googlemail.com> wrote:
>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).
>
> Robert I think they are:
> # vim: sts=2 sw=2 expandtab nu tw=0:
>
> class A
> def a
> def b
> 42
> end
> end
>
> end
>
> p A.new.methods.grep(/^b$/)
> A.new.b
>
> nested.rb:13: undefined method `b' for #<A:0xb7e337a0> (NoMethodError)
>
> Did you overlook David's post?
> I get exactly the same behavior than he does on a 1.8.5 Zenwalk
> I have the impression that OP got the victim of a "leftover" in his irb
> session.

Perhaps the OP was, but I think that Robert's statements are still correct:

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw