From: ES Date: 2005-05-17T06:32:30+09:00 Subject: Re: infinite number of singleton_classes Le 16/5/2005, "Ara.T.Howard@noaa.gov" a �crit: >On Tue, 17 May 2005, ES wrote: > >>> class Clothes >>> class Pocket < ::Pocket >>> end >>> end >>> >>> class Shirts >>> class Pocket < ::Pocket >>> end >>> end >>> >>> now this is a 'has-a' relationship: a Pants 'has-a' Pocket class >>> (Pants::Pocket) and Shirt 'has-a' Pocket class (Shirt::Pocket). there __is_= >> _ >>> a subtle 'is-a' relationshiop between pocket classes : a Shirt::Pocket 'is-a= >> ' >>> ::Pocket and a Pant::Pocket 'is-a' Pocket. however we do not (necessarily) >>> have : Shirt::Pocket 'is-a' Pants::Pocket. >> > > >> No, that would imply Shirt::Pocket < Pants::Pocket. > >how do you figure: > > harp:~ > cat a.rb > class Pocket; end > class Clothes; class Pocket < ::Pocket; end; end > class Shirts; class Pocket < ::Pocket; end; end > > p Clothes::Pocket.ancestors > p Shirts::Pocket.ancestors > > harp:~ > ruby a.rb > [Clothes::Pocket, Pocket, Object, Kernel] > [Shirts::Pocket, Pocket, Object, Kernel] > >?? Er, I think I was too curt. I meant to say, "No, we do not necessarily have Shirt::Pocket is-a Pants::Pocket, _that_ would imply Shirt::Pocket < Pants::Pocket. However..." I was agreeing with you on that point but disagreeing later :) >> However, I think it is > profoundly faulty to imply there is not a >> significant relationship between the two. >> Both children should share the traits of their parent but not those >> of their siblings. > >but this is exactly the case? in the above both pocket classes share the >traits of their common parent, Pocket, -- Yes, I was merely pointing out that I thought you were perhaps not describing the relationship of the siblings accurately. > -- and neither one shares that of their >siblings. this is precisely the case of singleton classes - they all descend >from [Class, Module, Object, Kernel] (the parent classes) and share those >traits - such as the ability to do 'self.attr :foobar'. i think the mistake >people are making is thinking that by doing > > foo = Foo::new > > singleton_class = class << foo; self; end > >is in thinking that singleton_class 'isa' foo. that is simply not the case. >rather 'singleton_class' is owned by foo. in otherwords foo 'has-a' >singleton_class and their is no parent child relationship between the two. Hm, that is a good point, and may well be a common confusion. >i think if the syntax were more like > > class Foo > singleton_class = generate_a_singleton_class > singleton_class.attr :bar > end > >vs. > > class Foo > class << self > attr :bar > end > end > >this might be more clear. visually the '<<' syntax is similar to '<' in 'A < >B' but it doesn't do anything similar - it only generates a special object >owned by the object calling the '<<' operator. > >> Your analysis is correct but the analogy is not quite, er >> analogous. To make it similar, each singleton (or pouch) >> would be a subclass of Pocket here. Therefore, while the >> methods defined in each of them have no relevance to the >> other (siblings' traits are not inherited), they _should_ >> share the methods from any common ancestors. > >they do. both singletons share the common attributes of their parents: > > [Class, Module, Object, Kernel] > >again the issue is that > > class C > class << self > this_is_a_child_of_Class_not_a_child_of_C = self > end > end > >so you are right and the analogy is too - all singleton classes share all the >traits of their common ancestors. it's just that those ancestors don't seem >to be who people think they are ;-) > >> So, if child_one.pouch and child_two.pouch are subclasses of parent.pouch, >> they should both share any methods in parent.pouch but not (necessarily) >> eachother. > >you'd be right if that were the relationship between parent/child classes and >their respective singleton classes - but with singleton_classes child_one.pouch >is a subclass of Pouch and child_two.pouch is a subclass of Pouch and child_one >and child_two are both children of Parent. check this out closely and you'll >see it for yourself: Agreed! Words fail me again; the 'are' should have been 'were' to signal a hypothetical. > harp:~ > cat a.rb > class Class > def pouch; class << self; self; end; end > end > class Parent > p ancestors > p pouch.ancestors > end > class ChildOne < Parent > p ancestors > p pouch.ancestors > end > class ChildTwo < Parent > p ancestors > p pouch.ancestors > end > > harp:~ > ruby a.rb > > [Parent, Object, Kernel] > [Class, Module, Object, Kernel] > > [ChildOne, Parent, Object, Kernel] > [Class, Module, Object, Kernel] > > [ChildTwo, Parent, Object, Kernel] > [Class, Module, Object, Kernel] > >so the only common ancestors between all the pouches of the above clases are >[Class, Module, Object, Kernel] and they definitely do inherit all the methods >from those ancestors. > >note that there is relationship __added__ to the pouches by being pouches of >parent/child classes : all pouches descend from the same Pouch class as in my >Pocket example above. > >for some reason i get the feeling we might be saying the same thing an i'm just >saying it badly? I are both think we uncommunicating miswell. Yes, I generally agree with what you are saying, definitely. My objection was merely to you (to me) not describing the 'common lineage' of the two singletons/pouches correctly, rather than the entire explanation. I was not clear about this, sorry. >cheers. > >-a E -- template void quack(duck& d) { d.quack(); }