From: Gennady Date: 2004-08-11T06:59:39+09:00 Subject: Re: Singleton class methods Robert Klemme wrote: > "Gennady" schrieb im Newsbeitrag > news:411926AD.1050408@tonesoft.com... > >>David A. Black wrote: >> >>>Hi -- >>> >>>On Wed, 11 Aug 2004, Gennady wrote: >>> >>> >>> >>>>Kyle Putnam wrote: >>>> >>>> >>>>>Hello, >>>>> >>>>>It seems these two syntaxes accomplish the same thing, or are there >>>>>differences? >>>>> >>>>> class Foo >>>>> class << self >>>>> def bar >>>>> # ... >>>>> end >>>>> end >>>>> end >>>>> >>>>>compared to... >>>>> >>>>> class Foo >>>>> def Foo.bar >>>>> # ... >>>>> end >>>>> end >>>>> >>>>>Cheers, >>>>> Kyle >>>>> >>>>> >>>> >>>>Exactly the same from the functionality point of view (it differs in >>>>implementation, though). I personally prefer the first form, as when it >>>>comes to renaming a class, you can do it in one place. Also with this >>>>form you can do other nice things such as defining class attribute >>>>accessors with attr_reader, attr_writer or attr_accessor. >>> >>> >>>One difference (I believe this was pointed out to me once by Guy >>>Decoux, in response to the same question) is the scope of constants. >>>If you open the new scope with << self, constants visible in method >>>definitions will be those of that singleton class, rather than those >>>of the original class. >> >>That's kind of what I meant. It seems like when you do >> >>class Foo >> def self.bar >> end >>end >> >>method "bar" is added to the list of methods of the original class Foo. > > > We have to be precise here to avoid confusion: did you mean as instance > method? Then that's wrong. This method is added to the singleton class the > same way in both approaches. I meant that "class << self" creates a separate anonymous singleton class that is associated (?) with an instance of class "Class" representing class "Foo", that is a singleton by itself, of course. That was my understanding of "class <<" idiom. The more I think about it, the more it seems like the same is happening when you do "def Foo.bar" as well. The only difference is that "def Foo.bar" reopens the original singleton class for "Foo", where the first occurrence of "class << self" in Foo definition creates a new anonymous singleton class (see bellow). So those 2 syntax forms might be quite similar in implementation, after all ;-) [skipped] > > > I'm afraid you're wrong here. :-) A difference is though that you can > define constants for the singleton class using the < can't with the direct approach AFAIK. When you have class Test end You can create constants both in class Test A=45 def self.f end end and in class Test class << self A=45 def f end end end cases. The difference is only where they are visible. [sparc.titan:13]prod_1> irb irb(main):001:0> class Test irb(main):002:1> A=45 irb(main):003:1> end => 45 irb(main):004:0> class Test irb(main):005:1> A=88 irb(main):006:1> end (irb):5: warning: already initialized constant A => 88 irb(main):007:0> class Test irb(main):008:1> class << self irb(main):009:2> A=55 irb(main):010:2> end irb(main):011:1> end => 55 NOTE: no warning "already initialized constant A" here. irb(main):012:0> Test::A => 88 irb(main):013:0> class Test irb(main):014:1> class << self irb(main):015:2> A=99 irb(main):016:2> end irb(main):017:1> end (irb):15: warning: already initialized constant A => 99 NOTE: and here we have the warning again. irb(main):018:0> class Test irb(main):019:1> def self.f irb(main):020:2> puts A irb(main):021:2> end irb(main):022:1> end => nil irb(main):023:0> Test.f 88 => nil irb(main):024:0> class Test irb(main):025:1> class << self irb(main):026:2> def f2 irb(main):027:3> puts A irb(main):028:3> end irb(main):029:2> end irb(main):030:1> end => nil irb(main):031:0> Test.f2 99 => nil > > Kind regards > > robert > >