From: Mark Hubbart Date: 2005-09-13T16:10:04+09:00 Subject: Re: confused by nested functions On 9/11/05, Devin Mullins wrote: > Yo -- > > David A. Black wrote: > > > On Sun, 11 Sep 2005, Devin Mullins wrote: > > > >> (I'm thinking the PickAxe may be wrong? about the private thing since > >> you can call #moo with an explicit receiver -- sounds more like > >> public. Can somebody explain?) > > > > > > I think the private thing depends on lexical scope. Since the nested > > definition of moo is not lexically a top-level definition, it isn't > > privatized. > > I'm not sure what you mean. Seems lexically top-level to me -- it's not > inside a class or module block. That it's inside a method doesn't seem > to make a difference: > > irb(main):001:0> def moo; puts 'moo' end > => nil > irb(main):002:0> nil.moo > moo > => nil Just a quick note: beware of IRB. when it comes to method and variable visibility, it doesn't always behave the same as in normal code: mark@eMac% irb ruby 1.8.2 (2004-12-25) on powerpc-darwin8.0 Welcome to Interactive Ruby def foo() :foo end ==>nil nil.foo ==>:foo mark@eMac% ruby < def foo() :foo end heredoc> p nil.foo heredoc> EOT -:2: private method `foo' called for nil:NilClass (NoMethodError) mark@eMac% > You know, if I weren't so !#%@#ing afraid of just reading the @#%#@ing > source code, I'd've had this question answered by now. > > >> #2: When Test.boo is called, moo is defined as an instance method on > >> Test. Test.boo returns nil, as before, but nil is not a Test object, > >> so the moo method does not exist. > > > > > > What I find interesting is this: > > > > Nesting a definition inside a class method, and nesting a definition > > inside an instance method, have exactly the same effect: an instance > > method is added to the class. In one case, this means "self"; in the > > other, it means "self.class". I'm not sure why it works this way. > > > Maybe the real rule is "one lexical layer up", which would take both > > to the class-definition scope that surrounds them. > > Precisely. It works like class variables -- it depends solely on the > *lexical* scope of the method definition. You could have written: > > class D > def bee > def mee > puts "mee" > end > end > end > module SomeOtherModule > def D.boo > def moo > puts "moo" > end > end > end > > D.boo > d = D.new > d.bee > > p (D.instance_methods - D.superclass.instance_methods) # includes only > mee & bee > p SomeOtherModule.instance_methods #includes only moo > > And yes, it is interesting. :) > > Devin > > >