Object specific methods and id

Hi,

If I create an object specifc method foo on my string instance obj, a new anonymous class (the singleton, I gather) is created and obj is considered an instance of that.

Also, every thing is an object (event classes). So how come,
obj.class.id
and
"someString".class.id
is the same?

According to the documentation on id: "The same number will be returned on all calls to id for a given object, and no two active objects will share an id."

Kind regards,

Thomas

If I create an object specifc method foo on my string instance obj, a
new anonymous class (the singleton, I gather) is created and obj is
considered an instance of that.

Also, every thing is an object (event classes). So how come,
obj.class.id
and
"someString".class.id
is the same?

You should be using object_id; but that won't change what you see.

According to the documentation on id: "The same number will be returned
on all calls to id for a given object, and no two active objects will
share an id."

Creating an eigenclass (singleton class) for an object does not change
the .class of that object.

irb(main):001:0> s1 = "hello"
=> "hello"
irb(main):002:0> s2 = "world"
=> "world"
irb(main):003:0> def s2.special_method; end
=> nil
irb(main):004:0> s1.class == s2.class
=> true
irb(main):005:0> s1.class
=> String
irb(main):006:0> s2.class
=> String

irb(main):008:0> s2eigenclass = class << s2; self; end
=> #<Class:#<String:0x2b813c8>>

irb(main):012:0> s2.class.instance_methods.grep /special/
=>

irb(main):013:0> s2eigenclass.instance_methods.grep /special/
=> ["special_method"]

···

On Feb 14, 3:59 pm, UpsNDowns <tnospamho...@povtal.org> wrote:

UpsNDowns wrote:

Hi,

If I create an object specifc method foo on my string instance obj, a
new anonymous class (the singleton, I gather) is created and obj is
considered an instance of that.

Also, every thing is an object (event classes). So how come,
obj.class.id
and
"someString".class.id
is the same?

They aren't:

puts String.class
puts 'hello'.class

--output:--
Class
String

puts String.class.object_id
puts 'hello'.class.object_id

--output:--
110210
105460

···

--
Posted via http://www.ruby-forum.com/\.

UpsNDowns wrote:

Hi,

If I create an object specifc method foo on my string instance obj, a
new anonymous class (the singleton, I gather) is created and obj is
considered an instance of that.

According to pickaxe2, that is correct. However, the anonymous class is
called an 'anonymous' for a reason: it has no name. So, what would
obj.class return if that were to retrieve the name of the anonymous
class? nil? I would imagine the anonymous class does not have a .class
attribute, so the lookup for .class proceeds up the inheritance chain,
something like this:

class Dog
  attr_accessor :name

  def initialize
    @name = "Rover"
  end

end

···

#-------------------

class IntermediateClass < Dog
end

#-------------------

class Puppy < IntermediateClass
end

p = Puppy.new
puts p.name

--output:--
Rover
--
Posted via http://www.ruby-forum.com/\.

The original poster was talking about a string instance
that has been specialized with a singleton method, not
the String class object.

UpnsNDowns: You have to be careful about thinking of the object
as an instance of its eigenclass. It is a useful analogy but it
is just that, an analogy.

Gary Wright

···

On Feb 14, 2008, at 6:19 PM, 7stud -- wrote:

UpsNDowns wrote:

If I create an object specifc method foo on my string instance obj, a
new anonymous class (the singleton, I gather) is created and obj is
considered an instance of that.

Also, every thing is an object (event classes). So how come,
obj.class.id
and
"someString".class.id
is the same?

They aren't:

puts String.class
puts 'hello'.class

It would return what it does:
irb(main):001:0> class << "foo"; self; end
=> #<Class:#<String:0x2b82264>>

The reason .class doesn't return the eigenclass has nothing to do with
it being 'hard' to represent. It's because it's still not the class of
the object. It's not a module, either, though it also behaves like
one. It is its own thing.

···

On Feb 14, 5:08 pm, 7stud -- <bbxx789_0...@yahoo.com> wrote:

According to pickaxe2, that is correct. However, the anonymous class is
called an 'anonymous' for a reason: it has no name. So, what would
obj.class return if that were to retrieve the name of the anonymous
class?

Also not true:

irb(main):002:0> class << "foo"; self; end.class
=> Class

The class is, unsurprisingly, an instance of Class.

···

On Feb 14, 5:08 pm, 7stud -- <bbxx789_0...@yahoo.com> wrote:

I would imagine the anonymous class does not have a .class
attribute...

Gavin Kistner wrote:

The reason .class doesn't return the eigenclass has nothing to do with
it being 'hard' to represent.

Who said anything about it being 'hard'?

According to pickaxe2, that is correct. However, the anonymous class is
called an 'anonymous' for a reason: it has no name. So, what would
obj.class return if that were to retrieve the name of the anonymous
class?

It would return what it does:
irb(main):001:0> class << "foo"; self; end
=> #<Class:#<String:0x2b82264>>

...which isn't that output. Maybe you shoot for accuracy rather than
quantity.

Gavin Kistner wrote:

···

On Feb 14, 5:08 pm, 7stud -- <bbxx789_0...@yahoo.com> wrote:
On Feb 14, 5:08�pm, 7stud -- <bbxx789_0...@yahoo.com> wrote:

�I would imagine the anonymous class does not have a .class
attribute...

Also not true:

irb(main):002:0> class << "foo"; self; end.class
=> Class

The class is, unsurprisingly, an instance of Class.

Thanks for your insightful post.

--
Posted via http://www.ruby-forum.com/\.

Thanks for the reply.

Gary Wright wrote:

UpnsNDowns: You have to be careful about thinking of the object
as an instance of its eigenclass. It is a useful analogy but it
is just that, an analogy.

Oh. I was reading the book by the programmatic programmers and I believe it says quite clearly that the object becomes an instance of the singleton. Anyway, do you have a reference (pref web) for the analogy?

Kind regards

Nothing comes to mind. This thread pointed out that if it was *really* an instance of the singleton class then instance.class would return the singleton class, but it doesn't. Another difference is that the singleton class and its superclass are outside the class hierarchy that created the instance in the first place. Another difference is that the instance exists before its singleton class, which is the opposite of the normal class/instance relationship.

These are the types of things I was getting at when I said that the analogy was imperfect.

Gary Wright

···

On Feb 15, 2008, at 2:14 PM, UpsNDowns wrote:

Thanks for the reply.

Gary Wright wrote:

UpnsNDowns: You have to be careful about thinking of the object
as an instance of its eigenclass. It is a useful analogy but it
is just that, an analogy.

Oh. I was reading the book by the programmatic programmers and I believe it says quite clearly that the object becomes an instance of the singleton. Anyway, do you have a reference (pref web) for the analogy?

Gary Wright wrote:

Nothing comes to mind. This thread pointed out that if it was *really* an instance of the singleton class then instance.class would return the singleton class, but it doesn't. Another difference is that the singleton class and its superclass are outside the class hierarchy that created the instance in the first place. Another difference is that the instance exists before its singleton class, which is the opposite of the normal class/instance relationship.

* instance.class is a method like any other so it can be overriden by the singleton, I think, so it can return whatever it wants. Indeed if I from the singleton class does ObjectSpace.each_object (self) {|x| puts x} only my instance is printed. (I suspect ObjectSpace gets help from the VM/runtime).

* Im not sure I understand what you mean by outside the hierachy. My understanding is that the singleton is subclasses the original class.

* As for the instance existing before the class, yeah I see that.

Kind regards

* instance.class is a method like any other so it can be overriden by the singleton, I think, so it can return whatever it wants. Indeed if I from the singleton class does ObjectSpace.each_object (self) {|x| puts x} only my instance is printed. (I suspect ObjectSpace gets help from the VM/runtime).

It can replace Object#klass, but it doesn't. Your ObjectSpace example is a good illustration of the singleton class/singleton object relationship models a class/instance relationship without actually being a class/instance relationship.

* Im not sure I understand what you mean by outside the hierachy. My understanding is that the singleton is subclasses the original class.

class A; end
class B < A; end

a = A.new
b = B.new

S = (class <<a; self; end) # a's singleton class

a.kind_of?(A) # true
a.kind_of?(S) # true, as if S were a subclass of A but...

B < A # true, B is a subclass of A
S < A # nil, S is not a subclass of A

b.class.superclass # A
B.superclass # A
S.superclass # A's Singleton Class, not A

I'm not trying to say that the relationship is entirely different from a class/instance relationship just that they are not identical relationships.

Gary Wright

···

On Feb 16, 2008, at 10:50 AM, UpsNDowns wrote:

Hi Gary, I grateful for you helping me on this.

(Though these things really confuses me:)

Gary Wright wrote:

Indeed if I from the singleton class does ObjectSpace.each_object (self) {|x| puts x} only my instance is printed. (I suspect

It can replace Object#klass, but it doesn't. Your ObjectSpace example is a good illustration of the singleton class/singleton object relationship models a class/instance relationship without actually being a class/instance relationship.

>
My understanding of each_object is that it finds all instances of a supplied class (it accepts other types of arguments). So, to me, taken at face value the example supports the case that there is a class/instance relationship?

* Im not sure I understand what you mean by outside the hierachy. My understanding is that the singleton is subclasses the original class.

class A; end
class B < A; end

a = A.new
b = B.new

S = (class <<a; self; end) # a's singleton class

a.kind_of?(A) # true
a.kind_of?(S) # true, as if S were a subclass of A but...

B < A # true, B is a subclass of A
S < A # nil, S is not a subclass of A

b.class.superclass # A
B.superclass # A
S.superclass # A's Singleton Class, not A

I would believe that b.class.superclass produces something like 'Object' as I would expect b.class to return an instance of the Class class. The Class class derives from Object.

If I do:

obj = 'Hello'

objSingletonClass = class<< obj
   def foo
     puts 'This is the foo method printing'
   end
   self
end

puts objSingletonClass.superclass

···

#--
I get :

#<Class:String>
Complete(0)

#--

Kind regards!

My understanding of each_object is that it finds all instances of a supplied class (it accepts other types of arguments). So, to me, taken at face value the example supports the case that there is a class/instance relationship?

OK, but the counter example is that obj.class is *not* the singleton class and the singleton class is not a subclass of obj.class.

What it boils down to is that Ruby's singleton mechanism introduces a class/instance relationship that is parallel to the standard class/instance relationship. If you try to describe one in terms of the other (or visa versa) you are going to get stuck somewhere along the way. I think it is better to think of them as parallel relationships rather than one being defined by the other.

David Black talks about the 'birth class' of an object vs. the 'singleton class' of an object. In both cases the object is an 'instance' of the class' but neither relationship can be defined in terms of the other.

* Im not sure I understand what you mean by outside the hierachy. My understanding is that the singleton is subclasses the original class.

class A; end
class B < A; end
a = A.new
b = B.new
S = (class <<a; self; end) # a's singleton class
a.kind_of?(A) # true
a.kind_of?(S) # true, as if S were a subclass of A but...
B < A # true, B is a subclass of A
S < A # nil, S is not a subclass of A
b.class.superclass # A
B.superclass # A
S.superclass # A's Singleton Class, not A

I would believe that b.class.superclass produces something like 'Object' as I would expect b.class to return an instance of the Class class. The Class class derives from Object.

No.

b.class # B, b is an instance of B
b.class.superclass # A, B is a subclass of A
b.class.superclass.superclass # Object, A is a subclass of Object

puts objSingletonClass.superclass
#<Class:String>

True, but '#<Class:String>' is simply a chuck of text returned by the #to_s method. Singleton classes come into existence when they are referenced and unless you explicitly assign them to a constant they will by anonymous (as in they will not have a string associated with their Class#name attribute). #to_s (and #inspect) actually ignores that name assignment though and just crafts its own output:

x = Object.new

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

puts xs.name # => ""
puts xs.to_s # => "#<Class:#<Object:0x4ad580>>"
puts xs.inspect # => "#<Class:#<Object:0x4ad580>>"

XS = xs
puts xs.name # => "XS"
puts xs.to_s # => "#<Class:#<Object:0x4ad580>>"
puts xs.inspect # => "#<Class:#<Object:0x4ad580>>"

xs_super = xs.superclass
puts xs_super.name # => ""
puts xs_super.to_s # => "#<Class:Object>"
puts xs_super.inspect # => "#<Class:Object>"

os = (class <<Object; self; end) # Object's singleton class
puts os.name # => ""
puts os.inspect # => "#<Class:Object>"

XSS = xs_super
puts xs_super.name # => "XSS"
puts xs_super.to_s # => "#<Class:Object>"
puts xs_super.inspect # => "#<Class:Object>"

···

On Feb 16, 2008, at 12:09 PM, UpsNDowns wrote:

Hi Gary,

Thanks a bunch! This discussion has been really helpful!

Apart from the 'direct' mistakes (like the prediction of what b.class.superclass would return) it has finally dawned on me that indeed the singletons are parallel.
In between my last post and your last, I read this:

http://www.chariotsolutions.com/slides/pdfs/rubyeast2007-black-PerObjectBehavior.pdf

which is attributed to some David Black and it talks about the birth classes etc. I assume it's this David Black you mentioned :). Im new to ruby, so who is David Black in the ruby community?

Alas, my problem now is, that an assignment for my CS class requires me to prove that the obj is an instance of the singleton. (And no, it's no trick question, the teacher has even lectured about it and proposed a solution at the labs--- which btw I don't buy).

>
> OK, but the counter example is that obj.class is *not* the singleton
> class and the singleton class is not a subclass of obj.class.
>
Pretending to be the devil's advocate, this could be explained away (I *guess*) by claiming that the singleton class could have provided a masking implementation of the class method.

I would say this much though: The singletons are fuzzy, (the slides from David Black ignores and belittles the importance of the implementation, and dare I say the principles behind them). It also seems to me that the results from various methods in ruby are inconsistent. (the each_object(self) trick--- or perhaps it's a matter of documenting that method)

Kind regards and thanks again.

Thomas.

Gary Wright wrote:

···

On Feb 16, 2008, at 12:09 PM, UpsNDowns wrote:

My understanding of each_object is that it finds all instances of a supplied class (it accepts other types of arguments). So, to me, taken at face value the example supports the case that there is a class/instance relationship?

OK, but the counter example is that obj.class is *not* the singleton class and the singleton class is not a subclass of obj.class.

What it boils down to is that Ruby's singleton mechanism introduces a class/instance relationship that is parallel to the standard class/ instance relationship. If you try to describe one in terms of the other (or visa versa) you are going to get stuck somewhere along the way. I think it is better to think of them as parallel relationships rather than one being defined by the other.

David Black talks about the 'birth class' of an object vs. the 'singleton class' of an object. In both cases the object is an 'instance' of the class' but neither relationship can be defined in terms of the other.

* Im not sure I understand what you mean by outside the hierachy. My understanding is that the singleton is subclasses the original class.

class A; end
class B < A; end
a = A.new
b = B.new
S = (class <<a; self; end) # a's singleton class
a.kind_of?(A) # true
a.kind_of?(S) # true, as if S were a subclass of A but...
B < A # true, B is a subclass of A
S < A # nil, S is not a subclass of A
b.class.superclass # A
B.superclass # A
S.superclass # A's Singleton Class, not A

I would believe that b.class.superclass produces something like 'Object' as I would expect b.class to return an instance of the Class class. The Class class derives from Object.

No.

b.class # B, b is an instance of B
b.class.superclass # A, B is a subclass of A
b.class.superclass.superclass # Object, A is a subclass of Object

puts objSingletonClass.superclass
#<Class:String>

True, but '#<Class:String>' is simply a chuck of text returned by the #to_s method. Singleton classes come into existence when they are referenced and unless you explicitly assign them to a constant they will by anonymous (as in they will not have a string associated with their Class#name attribute). #to_s (and #inspect) actually ignores that name assignment though and just crafts its own output:

x = Object.new

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

puts xs.name # => ""
puts xs.to_s # => "#<Class:#<Object:0x4ad580>>"
puts xs.inspect # => "#<Class:#<Object:0x4ad580>>"

XS = xs
puts xs.name # => "XS"
puts xs.to_s # => "#<Class:#<Object:0x4ad580>>"
puts xs.inspect # => "#<Class:#<Object:0x4ad580>>"

xs_super = xs.superclass
puts xs_super.name # => ""
puts xs_super.to_s # => "#<Class:Object>"
puts xs_super.inspect # => "#<Class:Object>"

os = (class <<Object; self; end) # Object's singleton class
puts os.name # => ""
puts os.inspect # => "#<Class:Object>"

XSS = xs_super
puts xs_super.name # => "XSS"
puts xs_super.to_s # => "#<Class:Object>"
puts xs_super.inspect # => "#<Class:Object>"

UpsNDowns wrote:

Im new to ruby, so who is David Black in the ruby community?

The author of "Ruby for Rails", one of the absolute best books on the OO side of Ruby.

(If you don't use Rails, don't let the title scare you! That book is VERY little about Rails.)

Best regards,

Jari Williamsson

Alas, my problem now is, that an assignment for my CS class requires me to prove that the obj is an instance of the singleton. (And no, it's no trick question, the teacher has even lectured about it and proposed a solution at the labs--- which btw I don't buy).

Well, prove the teacher wrong showing that their definition of 'instance of' is ambiguous. You could take a test driven approach and write some tests that describe the expected behavior of a class and its instance. Then try the tests against different types of objects:

   class/instance
   singleton-class/instance

I'll bet you find that there are some tests that work with class/instance that won't work with singleton-class/instance but that the tests that the teacher suggested work for both cases.

Pretending to be the devil's advocate, this could be explained away (I *guess*) by claiming that the singleton class could have provided a masking implementation of the class method.

I suppose but then you have to explain why the singleton class didn't provide a masking implementation of its own superclass method, which you don't want it to do since that would break
various other semantics in particular the behavior of singleton classes of classes and method lookup on class instances.

I would say this much though: The singletons are fuzzy, (the slides from David Black ignores and belittles the importance of the implementation, and dare I say the principles behind them).

Well, there is an unresolved issue from Matz perspective. The core idea is the notion of per-object methods. That idea is currently implemented via the singleton class mechanism but, as we've discovered, somewhat awkwardly with respect to the normal inheritance hierarchy. Within the language itself, there isn't even a 'name' for the construct since it is only accessible via an expression:

    (class <<x; self; end)

The most common terminology for that expression is 'singleton class' but some people like 'eigenclass' to distinguish the construct from a regular class that guarantees a single instance.
But in either case, you won't find 'singletonclass' or 'eigenclass' as a method name or keyword in the language or libraries.

Personally I'd really like to have a name instead of the expression since it seems everyone ends up defining their own name anyway via something like:

class Object
   def eclass
     (class <<self; self; end)
   end
end

But the particular name is different from one project to the next (eclass, metaclass, sclass, singleton_class, eigen_class, etc.)

I believe Matz said that he has finally decided that per-object methods are really and truly going to be officially standardized as instance methods of a 'per-object' class but he still hasn't committed to a standardized term for that 'per-object' class. So for now it is still known officially as 'the class returned by the expression (class <<x; self; end)'.

Gary Wright

···

On Feb 16, 2008, at 3:30 PM, UpsNDowns wrote:

Has the instructor given a definition of what it means to say that an
object is an instance of a class? Very frequently, in academic
settings, a very precise definition of terms will be applied that may
not exactly match any particular intuition, and there certainly are
definitions where that might be true.

Though, really, I'd argue that the singleton class of an object in
Ruby is really effectively a more like a Class that inherits from the
class of the object and is mixed in than it is like the class that the
object is an instance of. (Though its not that, either, since regular
classes can't be mixed in normally.)

After all, if you have an Array foo, then in Ruby 1.9:

c = class <<foo; self; end
foo.instance_of? c # => false
foo.kind_of? c # => true
c.superclass # => Array
foo.class # => Array
c.superclass == foo.class # => true

Note that this is different in Ruby 1.8.6:

c = class <<foo; self; end
foo.instance_of? c # => false
foo.kind_of? c # => true
c.superclass # => #<Class:Array>
foo.class # => Array
c.superclass == foo.class # => false

···

On Feb 16, 2008 12:30 PM, UpsNDowns <tnospamhomas@povtal.org> wrote:

Alas, my problem now is, that an assignment for my CS class requires me
to prove that the obj is an instance of the singleton. (And no, it's no
trick question, the teacher has even lectured about it and proposed a
solution at the labs--- which btw I don't buy).

Hi Jari,

Jari Williamsson wrote:

ruby, so who is David Black in the ruby community?

The author of "Ruby for Rails", one of the absolute best books on the OO side of Ruby.

Oh. I see. Thanks! I've just ordered the book on amazon.

Kind regards.

Hi Gary,

Thanks again.

Just a small note.

>

Pretending to be the devil's advocate, this could be explained away (I *guess*) by claiming that the singleton class could have provided a masking implementation of the class method.

I suppose but then you have to explain why the singleton class didn't provide a masking implementation of its own superclass method, which you don't want it to do since that would break
various other semantics in particular the behavior of singleton classes of classes and method lookup on class instances.

Strangely (or not) the class method cannot be overriden in the singleton. The argument about hacking the class method is somewhat buggered I believe (now). Since if B < A and I override the class method in B to return something else, it has no impact on what methods I can call on instances of B.