It might be that Kernel#self_class might be more descriptive and also help prevent confusion between singleton classes and Singleton classes. If we're going to be making this essential feature of Ruby easy to use, then we might as well try reprogramming the Ruby community as well to make this feature clearer and easier to use and understand, too. --Austin Ziegler
Hi --
I don't think the singleton/Singleton thing will go away that easily -- unless Singleton gets renamed. self_class doesn't really express what the method is doing; it's so similar to self.class, and any explanation of why would probably include discussion of [Ss]ingleton anyway. It gives you an object's singleton class, just as instance_methods gives you its instance methods, etc., and I think in the long run that's the clearest way.
-- David Black
Well, it was a thought. Maybe an RCR for Singleton to be renamed to SingletonPattern? Yes, it will break things, but it's a matter of implementing a Pattern. --Austin Ziegler
I would suggest a more rubyesque implementation.
module Kernel
def singleton_class(&block)
s = class << self
self
end
s.class_eval(&block) if block
s
end
end
-- Matthias Georgi
I'd rather keep it strictly parallel to, and congruent with, #class. One of the main goals of this RCR is to put an object's class and singleton class in as close to the same conceptual and semantic category as possible, so any special casing is at cross purposes with the goal. (I also would not agree that the block version is more rubyesque, but that's like debating readability or intuitiveness -- i.e., more or less pointless :-)
-- David Black
Oh, I overlooked this parallelism, so I agree with you. I'm just not clear about metaclasses, they are the singleton classes of classes. Are they different in an import way from singleton classes of objects ? (I think they are created at class definition time, but maybe that makes no different in usage, I guess.)
-- Matthias Georgi
IMHO there is another reasonable implementation of singleton_class:
module Kernel
def singleton_class
if has_any_singleton_method?
class << self; self; end
else
nil
end
end
end
That way one can easily recognize whether this instance has any per instance methods defined.
Btw: Why did you suggest to put it into Kernel, IMHO Object is the more appropriate place to put it.
-- Robert Klemme
The object can have a singleton class without having any singleton methods. If you want to return nil if the object has no singleton class, then you need:
module Kernel
def singleton_class
if has_singleton?
class << self; self; end
else
nil
end
end
end
Where singleton? cannot be written in Ruby, but must be written in C as:
VALUE has_singleton(VALUE self)
{
return FL_TEST(RBASIC(self)->klass, FL_SINGLETON) ? Qtrue : Qfalse;
}
Also, note that returning nil breaks David's original use of singleton_class, since you can now no longer write:
obj.singleton_class.class_eval
if the object has no singleton class. A parameter could be added to create the singleton class if it doesn't exist, or the two could be split into bang and non-bang versions, but I don't like either solution. Better IMO would be to have singleton_class always return a singleton class (creating it if it doesn't exist) and add a method to determine if an object currently has a singleton class.
-- Paul Brannan
I'd personally prefer #instance_class over #singleton_class, but either addition would be a boon to the language, IMO.
Yes, this should definitely go in.
However, I too am a little concerned about the name. While singleton classes are technically singletons (since they only ever have one instance), the term ``singleton class'' might be a little bit more confusing than necessary. It _is_ the current Ruby term, so the method should definitely go in under the name #singleton_class, but maybe it should have an alias? (Certainly, trying to make room by renaming the Singleton class would turn out to be even more confusing, since the term ``singleton'' is well-established throughout the object-oriented community.)
The suggested name #instance_class avoids the singleton mess, but creates a sizable mess of its own. You run into problems like this:
class Object
def instance_class
class << self ; self end
end
def define_instance_method name, &body
instance_class.class_eval { define_method name, &body }
end
end
Here you have a situation where defining an ``instance method'' (the natural choice of term for a method of the ``instance class'') on a class is not reflected in the Class#instance_methods collection. The problem, of course, is the unavoidable confusion that arises because classes both _produce_ instances and _are_ themselves instances.
The name #instance_class thus ends up being just as confusing as #singleton_class. Another obvious candidate is #private_class, which is, again, just as confusing (I don't think I have to be any more specific here).
The ideal solution would be to choose a name that avoids overloading already-established terms like ``singleton,'' ``instance,'' and ``private''. We could just call it Object#own_class --- after all, singleton classes are really a just way to give any particular object its very _own_ class. As it happens, I think this name is rather evocative and pedagogical. And it does indeed give you more freedom of expression with respect to ambiguity:
class Object
def own_class
class << self ; self end
end
def define_own_method name, &body
own_class.class_eval { define_method name, &body }
end
end
No confusion in sight there.
I'm slowly starting to realize that I lack a definitive point to make here, so I'll end this.
In any case, I do insist that the alias #singleton_class be put in. I personally prefer that name over both #instance_class and #own_class, and it seems unlikely that anyone should really be confused by the terminology overlap, once they fully understand both concepts.
Voting strongly in favor.
I wrote that, for the record.
-- Daniel Brockman
I think it might even make sense to add two methods instead of one. One that returns nil if the object has no singleton class yet and one that creates a new singleton class for it and returns that.
The first is neccessary so that no useless singleton classes get created, and that you can test whether a singleton class exists. The second is needed so that you can easily create a singleton class (and singleton methods) of an object without the class << syntax.
-- Zsban Ambrus
Hi Zsban --
Under what circumstances would you care whether a singleton class exists if you're not going to use it?
David Black
It might be that Kernel#self_class might be more descriptive and also help prevent confusion between singleton classes and Singleton classes. If we're going to be making this essential feature of Ruby easy to use, then we might as well try reprogramming the Ruby community as well to make this feature clearer and easier to use and understand, too. --Austin Ziegler
Hi --
I don't think the singleton/Singleton thing will go away that easily -- unless Singleton gets renamed. self_class doesn't really express what the method is doing; it's so similar to self.class, and any explanation of why would probably include discussion of [Ss]ingleton anyway. It gives you an object's singleton class, just as instance_methods gives you its instance methods, etc., and I think in the long run that's the clearest way.
-- David Black
Well, it was a thought. Maybe an RCR for Singleton to be renamed to SingletonPattern? Yes, it will break things, but it's a matter of implementing a Pattern. --Austin Ziegler
I would suggest a more rubyesque implementation.
-- Matthias Georgi
I'd rather keep it strictly parallel to, and congruent with, #class. One of the main goals of this RCR is to put an object's class and singleton class in as close to the same conceptual and semantic category as possible, so any special casing is at cross purposes with the goal. (I also would not agree that the block version is more rubyesque, but that's like debating readability or intuitiveness -- i.e., more or less pointless :-)
-- David Black
Oh, I overlooked this parallelism, so I agree with you. I'm just not clear about metaclasses, they are the singleton classes of classes. Are they different in an import way from singleton classes of objects ? (I think they are created at class definition time, but maybe that makes no different in usage, I guess.)
-- Matthias Georgi
IMHO there is another reasonable implementation of singleton_class:
That way one can easily recognize whether this instance has any per instance methods defined.
Btw: Why did you suggest to put it into Kernel, IMHO Object is the more appropriate place to put it.
-- Robert Klemme
The object can have a singleton class without having any singleton methods. If you want to return nil if the object has no singleton class, then you need:
Where singleton? cannot be written in Ruby, but must be written in C as:
Also, note that returning nil breaks David's original use of singleton_class, since you can now no longer write:
if the object has no singleton class. A parameter could be added to create the singleton class if it doesn't exist, or the two could be split into bang and non-bang versions, but I don't like either solution. Better IMO would be to have singleton_class always return a singleton class (creating it if it doesn't exist) and add a method to determine if an object currently has a singleton class.
-- Paul Brannan
I'd personally prefer #instance_class over #singleton_class, but either addition would be a boon to the language, IMO.
Yes, this should definitely go in.
However, I too am a little concerned about the name. While singleton classes are technically singletons (since they only ever have one instance), the term ``singleton class'' might be a little bit more confusing than necessary. It _is_ the current Ruby term, so the method should definitely go in under the name #singleton_class, but maybe it should have an alias? (Certainly, trying to make room by renaming the Singleton class would turn out to be even more confusing, since the term ``singleton'' is well-established throughout the object-oriented community.)
The suggested name #instance_class avoids the singleton mess, but creates a sizable mess of its own. You run into problems like this:
Here you have a situation where defining an ``instance method'' (the natural choice of term for a method of the ``instance class'') on a class is not reflected in the Class#instance_methods collection. The problem, of course, is the unavoidable confusion that arises because classes both _produce_ instances and _are_ themselves instances.
The name #instance_class thus ends up being just as confusing as #singleton_class. Another obvious candidate is #private_class, which is, again, just as confusing (I don't think I have to be any more specific here).
The ideal solution would be to choose a name that avoids overloading already-established terms like ``singleton,'' ``instance,'' and ``private''. We could just call it Object#own_class --- after all, singleton classes are really a just way to give any particular object its very _own_ class. As it happens, I think this name is rather evocative and pedagogical. And it does indeed give you more freedom of expression with respect to ambiguity:
No confusion in sight there.
I'm slowly starting to realize that I lack a definitive point to make here, so I'll end this.
In any case, I do insist that the alias #singleton_class be put in. I personally prefer that name over both #instance_class and #own_class, and it seems unlikely that anyone should really be confused by the terminology overlap, once they fully understand both concepts.
Voting strongly in favor.
I wrote that, for the record.
-- Daniel Brockman
I think it might even make sense to add two methods instead of one. One that returns nil if the object has no singleton class yet and one that creates a new singleton class for it and returns that.
The first is neccessary so that no useless singleton classes get created, and that you can test whether a singleton class exists. The second is needed so that you can easily create a singleton class (and singleton methods) of an object without the class << syntax.
-- Zsban Ambrus
Hi Zsban --
Under what circumstances would you care whether a singleton class exists if you're not going to use it?
David Black