Is singleton class of an object already created?

I would like to know is there any ways to check is singleton class of an
object already created?

ex: obj.singleton_class_defined?

Samnang C. wrote in post #972157:

I would like to know is there any ways to check is singleton class of an
object already created?

ex: obj.singleton_class_defined?

As an indirect test, you can’t Marshal any object with a singleton class
(although there are other kinds of object that you can’t Marshal either)

irb(main):001:0> foo = “abc”
=> “abc”
irb(main):002:0> (Marshal.dump(foo) && false) rescue true
=> false
irb(main):003:0> def foo.zzz; end
=> nil
irb(main):004:0> (Marshal.dump(foo) && false) rescue true
=> true

I would like to know is there any ways to check is singleton class of an
object already created?

Perhaps you need a method to determine the presence of singleton
methods. In Ruby 1.9.2 you have the Object#singleton_methods that
returns an array of singleton methods defined on the object.

Flanagan, and Matz’s book always talks about “opening” the eigenclass,
and not defining one. I guess that a singleton class always exists for
an object, whether a singleton method for that object exists or not.
You can always get a reference to the eigenclass of the object with
“class << object; self; end”, where object can be any object (that
allows singleton methods to be defined on them).

Anurag P. wrote in post #972264:

I guess that a singleton class always exists for
an object, whether a singleton method for that object exists or not.

Sure, singleton class always be there, and it inserted in the
inheritance chain before the objects “real” class when the first we need
it. But I would like to generate a diagram of an object’s ancestors, if
the object has used singleton class, then it will show in diagram, but
it doesn’t if object hasn’t used singleton class yet.

Could you simply count singleton_methods? If singleton_methods returns
an empty array, no singleton_class is present. Could easily add that
method to the object class and call it on anything you wanted. But
this strategy equates an empty singlton_method query with not having a
singleton_class. I am not sure that is exactly correct. Though
practically speaking, it seems equivalent to me.
Tim

class Object
def singleton_class?
self.singleton_methods.length == 0 ? false : true
end
end

a = ‘’
p a.singleton_class?
=> false

def a.singleton_method_for_a
end
p a.singleton_class?
=> true

I’m not sure every time we invoke ‘singleton_methods’, then it will
create the singleton class if it doesn’t exist yet.

On Tue, Jan 4, 2011 at 9:00 PM, timr [email protected] wrote:

class Object
def singleton_class?
self.singleton_methods.length == 0 ? false : true
end
end

Really small point here, and not really on topic, but this is a little
around the houses and can be slightly improved:

class Object
def singleton_class?
!self.singleton_methods.empty?
end
end

Or just != 0, since it’ll return the true/false without the need for a
ternary.

On Wed, Jan 5, 2011 at 2:36 AM, Samnang C. [email protected]
wrote:

I’m not sure every time we invoke ‘singleton_methods’, then it will
create the singleton class if it doesn’t exist yet.

Apparently it doesn’t according to Brian’s test:

irb(main):001:0> x=“foo”
=> “foo”
irb(main):002:0> Marshal.dump(x)
=> “\x04\bI”\bfoo\x06:\rencoding"\nCP850"
irb(main):003:0> x.singleton_methods
=> []
irb(main):004:0> Marshal.dump(x)
=> “\x04\bI”\bfoo\x06:\rencoding"\nCP850"
irb(main):005:0> def x.a;end
=> nil
irb(main):006:0> Marshal.dump(x)
TypeError: singleton can’t be dumped
from (irb):6:in dump' from (irb):6 from /opt/bin/irb19:12:in
irb(main):007:0>

Kind regards

robert

I just found that even though a singleton method is removed, the
receiver is still considered a singleton and cannot be dumped.


foo = Object.new

def foo.bar
‘foo.bar’
end

p foo.singleton_methods # => [:bar]

class << foo
undef bar
end

p foo.singleton_methods # => []
Marshal.dump(foo) # error


Looking inside marhsal.c, the following check routine is found:

if (RCLASS_M_TBL(klass)->num_entries ||
(RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1)) {
rb_raise(rb_eTypeError, “singleton can’t be dumped”);
}

It seems that the record remains in some dispatch table even if
Object#singleton_methods returns an empty array.

On Wed, Jan 5, 2011 at 11:24 AM, Adam P. [email protected]
wrote:

around the houses and can be slightly improved:
I couldn’t agree more! Using ternary operator with “false” and “true”
is not needed most of the time. (Only exception I would concede is to
avoid leakage of references - but then you can as well do “!! expr”.)

class Object
def singleton_class?
!self.singleton_methods.empty?
end
end

Or just != 0, since it’ll return the true/false without the need for a
ternary.

Or just

class Object
def singleton_class?
!singleton_methods.empty?
end
end

Now we can wonder whether this is worth a method at all… :slight_smile:

Kind regards

robert

Try reporting on http://redmine.ruby-lang.org/ . They are usually
helpful, and it lets you have that fix for the next ruby release.

in YARV and MRI, the singleton class always exists for a class (T_CLASS)
(it is
created on class creation), but is created lazily for ordinary objects
(T_OBJECTs).

Samnang C. wrote in post #972157:

I would like to know is there any ways to check is singleton class of an
object already created?

ex: obj.singleton_class_defined?