Is singleton class of an object already created?

S

Samnang Chhun

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

ex: obj.singleton_class_defined?
 
B

Brian Candler

Samnang Chhun 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
 
A

Anurag Priyam

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

Samnang Chhun

Anurag Priyam 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.
 
T

timr

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
 
S

Samnang Chhun

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

Robert Klemme

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 `<main>'
irb(main):007:0>

Kind regards

robert
 
A

Adam Prescott

[Note: parts of this message were removed to make it a legal post.]

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

Robert Klemme

Really small point here, and not really on topic, but this is a little
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
=A0def singleton_class?
=A0 =A0!self.singleton_methods.empty?
=A0end
end

Or just !=3D 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... :)

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
S

Su Zhang

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 records remains in some dispatch table even if
Object#singleton_methods returns an empty array.
 
J

John Mair

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

Samnang Chhun wrote in post #972157:
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top