object specific methods and id

U

UpsNDowns

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
 
P

Phrogz

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"]
 
7

7stud --

UpsNDowns said:
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
 
G

Gary Wright

puts String.class
puts 'hello'.class

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
 
7

7stud --

UpsNDowns said:
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
 
P

Phrogz

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

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

Phrogz

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

7stud --

Gavin said:
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'?
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 said:
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.
 
U

UpsNDowns

Thanks for the reply.

Gary said:
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
 
G

Gary Wright

Thanks for the reply.



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?

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
 
U

UpsNDowns

Gary said:
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
 
G

Gary Wright

* 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
 
U

UpsNDowns

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

(Though these things really confuses me:)

Gary said:
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?
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!
 
G

Gary Wright

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.
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>"
 
U

UpsNDowns

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

Jari Williamsson

UpsNDowns said:
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
 
G

Gary Wright

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
 
U

UpsNDowns

Hi Jari,

Jari said:
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.
 
C

Christopher Dicely

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

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
 
U

UpsNDowns

Hi Gary,

Thanks again.

Just a small note.
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,295
Latest member
EmilG1510

Latest Threads

Top