Singleton class methods

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

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.

Gennady.

"Gennady" <gfb@tonesoft.com> schrieb im Newsbeitrag
news:4118FEE9.10002@tonesoft.com...

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

Where exactly do you see this difference?

I personally prefer the first form, as when it
comes to renaming a class, you can do it in one place.

This is also possible with

class Foo
  def self.bar
            # ...
  end
end

I base my decision which idiom to use on the number of methods. If it's
just one or two, I usually take the def self.foo approach.

Also with this
form you can do other nice things such as defining class attribute
accessors with attr_reader, attr_writer or attr_accessor.

Yep!

Kind regards

    robert

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.

David

--
David A. Black
dblack@wobblini.net

David A. Black wrote:

Hi --

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.

On the other hand, for

class Foo
   class << self
     def bar
     end
   end
end

a singleton class is created for class object "Foo" and method "bar" is defined in that singleton class, with all consequences. Hence, the difference in implementation.

It is how I see it. I may be completely wrong, though.

Gennady.

···

On Wed, 11 Aug 2004, Gennady wrote:

David

Robert Klemme wrote:

"Gennady" <gfb@tonesoft.com> schrieb im Newsbeitrag
news:4118FEE9.10002@tonesoft.com...

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

Where exactly do you see this difference?

Please see my reply to David Black's message, I really meant to place it here, sorry.

I personally prefer the first form, as when it
comes to renaming a class, you can do it in one place.

This is also possible with

class Foo
  def self.bar
            # ...
  end
end

I base my decision which idiom to use on the number of methods. If it's
just one or two, I usually take the def self.foo approach.

With "class << self" form it is also convenient to fold all class methods at once in vim, I like that :slight_smile:

···

Also with this
form you can do other nice things such as defining class attribute
accessors with attr_reader, attr_writer or attr_accessor.

Yep!

Kind regards

    robert

"Gennady" <gfb@tonesoft.com> schrieb im Newsbeitrag
news:411926AD.1050408@tonesoft.com...

David A. Black wrote:
> Hi --
>
>
>
>>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.

$ irbs

class Foo;end

=> nil

class Foo
class <<self
p( instance_methods.include?( "bar" ) )
end
end

false
=> nil

class Foo
def self.bar;end
end

=> nil

class Foo
class <<self
p( instance_methods.include?( "bar" ) )
end
end

true
=> nil

On the other hand, for

class Foo
   class << self
     def bar
     end
   end
end

a singleton class is created for class object "Foo" and method "bar" is
defined in that singleton class, with all consequences. Hence, the
difference in implementation.

It is how I see it. I may be completely wrong, though.

I'm afraid you're wrong here. :slight_smile: A difference is though that you can
define constants for the singleton class using the <<self idiom while you
can't with the direct approach AFAIK.

Kind regards

    robert

···

> On Wed, 11 Aug 2004, Gennady wrote:

Both create a singleton method, but the scoping is different.
See
http://www.ruby-talk.com/blade/57274
and http://www.ruby-talk.com/cgi-bin/scat.rb/ruby/ruby-talk/57382

···

On Wed, Aug 11, 2004 at 04:47:17AM +0900, Gennady wrote:

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.

On the other hand, for

class Foo
  class << self
    def bar
    end
  end
end

a singleton class is created for class object "Foo" and method "bar" is
defined in that singleton class, with all consequences. Hence, the
difference in implementation.

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Robert Klemme wrote:

"Gennady" <gfb@tonesoft.com> schrieb im Newsbeitrag
news:411926AD.1050408@tonesoft.com...

David A. Black wrote:

Hi --

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

[skipped]

I'm afraid you're wrong here. :slight_smile: A difference is though that you can
define constants for the singleton class using the <<self idiom while you
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

···

On Wed, 11 Aug 2004, Gennady wrote:

Kind regards

    robert

Hi --

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

I'm not clear on your original/new distinction here. Each object can
have a maximum of one singleton class; so if Foo doesn't have one, it
gets created (when you do "def Foo.meth" or "class Foo; class << self"
or class << Foo). So there's no original vs. new singleton class for
a given object; it's always the same one.

(And of course the object doesn't have to be a Class object -- it can
be any object.)

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.

Yes -- see my earlier post on this point. This is just a case of the
fact that you can define constants in any class scope; and in your
example, both Test and Test's singleton class are Class objects.

David

···

On Wed, 11 Aug 2004, Gennady wrote:

--
David A. Black
dblack@wobblini.net

Your example clears most of this up, for me anyway. However, is there a
way to access this other scope? Obviously Test::A accesses the
non-singleton(?) class's constant. Is this other scope even accessable
from outside the singleton class?

irb(main):001:0> class << self
irb(main):002:1> CONSTANT = 50
irb(main):003:1> end
=> 50
irb(main):005:0> self.class::CONSTANT
NameError: uninitialized constant CONSTANT
        from (irb):5
irb(main):006:0> ::CONSTANT
NameError: uninitialized constant CONSTANT
        from (irb):6
irb(main):007:0> class << self
irb(main):008:1> CONSTANT
irb(main):009:1> end
=> 50

···

On Tue, 2004-08-10 at 17:59, Gennady wrote:

Robert Klemme wrote:

<<snip>>

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

David A. Black wrote:

Hi --

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

I'm not clear on your original/new distinction here. Each object can
have a maximum of one singleton class; so if Foo doesn't have one, it
gets created (when you do "def Foo.meth" or "class Foo; class << self"
or class << Foo). So there's no original vs. new singleton class for
a given object; it's always the same one.

irb(main):001:0> class Foo
irb(main):002:1> A=10
irb(main):003:1> end
=> 10
irb(main):004:0> class Foo
irb(main):005:1> def self.f1
irb(main):006:2> puts A
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> class << Foo
irb(main):010:1> A=20
irb(main):011:1> end
=> 20
irb(main):012:0> class << Foo
irb(main):013:1> def f2
irb(main):014:2> puts A
irb(main):015:2> end
irb(main):016:1> end
=> nil
irb(main):017:0> Foo.f1
10
=> nil
irb(main):018:0> Foo.f2
20

At least for "def Foo.f1" and "class << Foo" it is not the same one: one holds "A=10" and another -- "A=20".

Nevermind, my only point in a reply to the original post was that 2 syntactic forms provide same functionality, but differ in implementation. Looks like I am wrong, implementation is quite similar ;-).

···

On Wed, 11 Aug 2004, Gennady wrote:

(And of course the object doesn't have to be a Class object -- it can
be any object.)

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.

Yes -- see my earlier post on this point. This is just a case of the
fact that you can define constants in any class scope; and in your
example, both Test and Test's singleton class are Class objects.

David

Your example clears most of this up, for me anyway. However, is there a
way to access this other scope? Obviously Test::A accesses the
non-singleton(?) class's constant. Is this other scope even accessable
from outside the singleton class?

irb(main):001:0> class << self
irb(main):002:1> CONSTANT = 50
irb(main):003:1> end
=> 50
irb(main):005:0> self.class::CONSTANT
NameError: uninitialized constant CONSTANT
        from (irb):5

try

class << self; FOO = 1; end

=> 1

class << self; self end::FOO

=> 1

···

On Wed, Aug 11, 2004 at 07:51:43AM +0900, Kyle Putnam wrote:

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Hi --

> Robert Klemme wrote:
>
> <<snip>>
>
> 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

Your example clears most of this up, for me anyway. However, is there a
way to access this other scope? Obviously Test::A accesses the
non-singleton(?) class's constant. Is this other scope even accessable
from outside the singleton class?

irb(main):001:0> class << self
irb(main):002:1> CONSTANT = 50
irb(main):003:1> end
=> 50
irb(main):005:0> self.class::CONSTANT
NameError: uninitialized constant CONSTANT
        from (irb):5
irb(main):006:0> ::CONSTANT
NameError: uninitialized constant CONSTANT
        from (irb):6
irb(main):007:0> class << self
irb(main):008:1> CONSTANT
irb(main):009:1> end
=> 50

It's the same as with any class: you can open its scope with the
'class' keyword (using "<< obj" to indicate the anonymous class you
want), or you can capture it in a constant or variable and class_eval
from there, and so on. For example (using a non-Class object, just
for a change of pace :slight_smile:

  x = "hi"
  class << x
    C = 1
  end

  xclass = (class << x; self; end)

  puts xclass::C # => 1

This (class << x; self; end) thing is rather unwieldy, but there's an
RCR pending for Kernel#singleton_class, which would then do for an
object's singleton class what #class does for its class of origin.
Here's that method, plus the above example rewritten to use it:

  module Kernel
    def singleton_class; class << self; self; end; end
  end

  x = "hi"
  x.singleton_class::C = 1 # (or const_set if you prefer)
  p x.singleton_class::C # => 1

David

···

On Wed, 11 Aug 2004, Kyle Putnam wrote:

On Tue, 2004-08-10 at 17:59, Gennady wrote:

--
David A. Black
dblack@wobblini.net

Hi --

···

On Wed, 11 Aug 2004, Gennady wrote:

David A. Black wrote:
> Hi --
>
> On Wed, 11 Aug 2004, Gennady wrote:
>
>
>>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).
>
>
> I'm not clear on your original/new distinction here. Each object can
> have a maximum of one singleton class; so if Foo doesn't have one, it
> gets created (when you do "def Foo.meth" or "class Foo; class << self"
> or class << Foo). So there's no original vs. new singleton class for
> a given object; it's always the same one.

irb(main):001:0> class Foo
irb(main):002:1> A=10
irb(main):003:1> end
=> 10
irb(main):004:0> class Foo
irb(main):005:1> def self.f1
irb(main):006:2> puts A
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> class << Foo
irb(main):010:1> A=20
irb(main):011:1> end
=> 20
irb(main):012:0> class << Foo
irb(main):013:1> def f2
irb(main):014:2> puts A
irb(main):015:2> end
irb(main):016:1> end
=> nil
irb(main):017:0> Foo.f1
10
=> nil
irb(main):018:0> Foo.f2
20

At least for "def Foo.f1" and "class << Foo" it is not the same one: one
holds "A=10" and another -- "A=20".

But only one of them is a singleton class; the other is simply Foo
itself :slight_smile: When you do def Foo.m, 'self' is Foo; but when you do class
<< Foo, 'self' is the anonymous singleton class of Foo. Thus the
constants are different.

David

--
David A. Black
dblack@wobblini.net

That makes it crystal clear! I was looking specifically for what you
demonstrated with xclass = (class << x; self; end).

Kernel#singleton_class seems like a great idea - had I seen that listed
from Object#methods it would've been obvious :slight_smile:

Thanks!
    Kyle

···

On Tue, 2004-08-10 at 19:27, David A. Black wrote:

Hi --

<<snip>>

It's the same as with any class: you can open its scope with the
'class' keyword (using "<< obj" to indicate the anonymous class you
want), or you can capture it in a constant or variable and class_eval
from there, and so on. For example (using a non-Class object, just
for a change of pace :slight_smile:

  x = "hi"
  class << x
    C = 1
  end

  xclass = (class << x; self; end)

  puts xclass::C # => 1

This (class << x; self; end) thing is rather unwieldy, but there's an
RCR pending for Kernel#singleton_class, which would then do for an
object's singleton class what #class does for its class of origin.
Here's that method, plus the above example rewritten to use it:

  module Kernel
    def singleton_class; class << self; self; end; end
  end

  x = "hi"
  x.singleton_class::C = 1 # (or const_set if you prefer)
  p x.singleton_class::C # => 1

David

David A. Black wrote:

Hi --

David A. Black wrote:

Hi --

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

I'm not clear on your original/new distinction here. Each object can
have a maximum of one singleton class; so if Foo doesn't have one, it
gets created (when you do "def Foo.meth" or "class Foo; class << self"
or class << Foo). So there's no original vs. new singleton class for
a given object; it's always the same one.

irb(main):001:0> class Foo
irb(main):002:1> A=10
irb(main):003:1> end
=> 10
irb(main):004:0> class Foo
irb(main):005:1> def self.f1
irb(main):006:2> puts A
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> class << Foo
irb(main):010:1> A=20
irb(main):011:1> end
=> 20
irb(main):012:0> class << Foo
irb(main):013:1> def f2
irb(main):014:2> puts A
irb(main):015:2> end
irb(main):016:1> end
=> nil
irb(main):017:0> Foo.f1
10
=> nil
irb(main):018:0> Foo.f2
20

At least for "def Foo.f1" and "class << Foo" it is not the same one: one holds "A=10" and another -- "A=20".

But only one of them is a singleton class; the other is simply Foo
itself :slight_smile: When you do def Foo.m, 'self' is Foo; but when you do class

That's where a slight misunderstanding might have occurred: I was calling "Foo itself" an original singleton class (isn't it? ;-)), and the one created by "class << Foo" -- an anonymous singleton class of Foo (i omitted word "anonymous" from my original reply, sorry).

···

On Wed, 11 Aug 2004, Gennady wrote:

On Wed, 11 Aug 2004, Gennady wrote:

<< Foo, 'self' is the anonymous singleton class of Foo. Thus the
constants are different.

David

Hi --

···

On Wed, 11 Aug 2004, Gennady wrote:

>>At least for "def Foo.f1" and "class << Foo" it is not the same one: one
>>holds "A=10" and another -- "A=20".
>
>
> But only one of them is a singleton class; the other is simply Foo
> itself :slight_smile: When you do def Foo.m, 'self' is Foo; but when you do class

That's where a slight misunderstanding might have occurred: I was
calling "Foo itself" an original singleton class (isn't it? ;-)), and
the one created by "class << Foo" -- an anonymous singleton class of Foo
(i omitted word "anonymous" from my original reply, sorry).

I realize that we should probably be saying 'virtual class' instead of
'singleton class' (at least, that's what shows up in the error
messages when you try to instantiate one) -- but either way, Foo isn't
one :slight_smile: It's just a regular class.

David

--
David A. Black
dblack@wobblini.net

David A. Black wrote:

Hi --

At least for "def Foo.f1" and "class << Foo" it is not the same one: one holds "A=10" and another -- "A=20".

But only one of them is a singleton class; the other is simply Foo
itself :slight_smile: When you do def Foo.m, 'self' is Foo; but when you do class

That's where a slight misunderstanding might have occurred: I was calling "Foo itself" an original singleton class (isn't it? ;-)), and the one created by "class << Foo" -- an anonymous singleton class of Foo (i omitted word "anonymous" from my original reply, sorry).

I realize that we should probably be saying 'virtual class' instead of
'singleton class' (at least, that's what shows up in the error
messages when you try to instantiate one) -- but either way, Foo isn't
one :slight_smile: It's just a regular class.

David

Hmm, I like "virtual class" much better. I used term "singleton" for describing Foo's class simply to reflect that there's only one instance of class "Class" representing "Foo". Seems like my terminology was misleading.

Gennady.

···

On Wed, 11 Aug 2004, Gennady wrote:

Hi --

David A. Black wrote:

> Hi --
>
>
>
>>>>At least for "def Foo.f1" and "class << Foo" it is not the same one: one
>>>>holds "A=10" and another -- "A=20".
>>>
>>>
>>>But only one of them is a singleton class; the other is simply Foo
>>>itself :slight_smile: When you do def Foo.m, 'self' is Foo; but when you do class
>>
>>That's where a slight misunderstanding might have occurred: I was
>>calling "Foo itself" an original singleton class (isn't it? ;-)), and
>>the one created by "class << Foo" -- an anonymous singleton class of Foo
>>(i omitted word "anonymous" from my original reply, sorry).
>
>
> I realize that we should probably be saying 'virtual class' instead of
> 'singleton class' (at least, that's what shows up in the error
> messages when you try to instantiate one) -- but either way, Foo isn't
> one :slight_smile: It's just a regular class.
>
>
> David
>
Hmm, I like "virtual class" much better. I used term "singleton" for
describing Foo's class simply to reflect that there's only one instance
of class "Class" representing "Foo". Seems like my terminology was
misleading.

It's not a very useful usage -- you'd have to call every object in
Ruby a 'singleton' then :slight_smile:

'Singleton class' has always had the problem that there's also the
Singleton module, so 'singleton class' can also mean a class that
includes that module. 'Virtual class' strikes me as possibly causing
confusion, or false expectations, due to the use of that term for very
different things in other languages. But I don't have a perfect term
for it by any means. (I think there was a discussion about this on
ruby-core or somewhere lately... couldn't find it in a quick search.)

David

···

On Wed, 11 Aug 2004, Gennady wrote:

> On Wed, 11 Aug 2004, Gennady wrote:

--
David A. Black
dblack@wobblini.net