Object#singleton_class in Ruby 1.9?

T

Thomas Sawyer

Robert said:
Actually I am totally against it, in core that is. It would be nice to
have a standard library extension for this, e.g. meta-ruby.
I was really impressed about by David's keynote at Rubyconf. Just
thought to share this thoughts in case I am not a minority.

You are against having a method altogether, you mean?

I take it because of the very nature singleton_methods / eigenmethods.
And, I'm guessing, you prescribe to the idea that the only good way to
the singleton "space" is to include modules into it, rather than
defining methods directly. There was a blog post around somewhere to
that effect. It was a good article. I wish I could dig it up now, but
I'm not finding it. Perhaps someone else has the link? In any case, if
that's what you mean, then I generally agree. That article was right,
there rarely is a good reason to define methods directly into the
singleton, one should be including a module with the methods defined in
it instead. The only exception may be class-level methods, but even then
using #extend deserves more merit.

Taking that idea to heart perhaps a reorientation on the matter is
warranted.
Consider this form in place of the usual 'class << self':

class X
extend Module.new {
...
}
end

Not quite as elegant since we can't use do...end. But if #extend could
take a block:

class X
extend do
...
end
end

Then the issue becomes transparent. Even for regular objects:

obj.extend do
...
end

This is not to say that a singleton_class/eigenclass method would never
be of use, but it would certainly mitigate the need for it a great deal.
(One might also take away from this that a better name for it, if it
were given a method name, would be #extension, but I mention that only
as an aside.)

T.
 
D

David A. Black

Actually I am totally against it, in core that is. It would be nice to
have a standard library extension for this, e.g. meta-ruby.
I was really impressed about by David's keynote at Rubyconf. Just
thought to share this thoughts in case I am not a minority.

I'd like to have a singleton_class method, but even if there isn't
one, I would definitely not like a meta-ruby standard extension. It
suggests much too clear a separation between programming and
metaprogramming in Ruby, whereas part of the coolness of the language
is how interoperative it all is (e.g., the very fact that singleton
methods are stored in classes, which in turn fit into the whole
class/object model in a predictable way).


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
J

James Gray

Definitely. I was implying that I don't think *too* many people hate
singleton_class, but don't get me wrong, even if matz added
Object#matz_is_awesome and had it do this operation, I'd be happy. :)

I've changing my vote. I now want:

matz_class()

No one can beat that. :)

James Edward Gray II
 
R

Robert Dober

I'd like to have a singleton_class method, but even if there isn't
one, I would definitely not like a meta-ruby standard extension. It
suggests much too clear a separation between programming and
metaprogramming in Ruby, whereas part of the coolness of the language
is how interoperative it all is (e.g., the very fact that singleton
methods are stored in classes, which in turn fit into the whole
class/object model in a predictable way).
Well please let me rephrase this:

I think #singleton_class is a great name. I want it, but rather than
in core in a standard library, or even a core class.
However that consideration was OT - 4 which I apologize - and it might
indeed be worth a discussion for 2.0 if 'nuff people think like that.

Back OnT, I really think it is too late to change #singleton_class it
has become so much used in Ruby's jargon.
I am well aware of the ambiguity with the Singleton pattern, but I
feel it is enough related to still be the ideal choice.

R.
 
S

Sean O'Halpin

Consider this form in place of the usual 'class << self':

class X
extend Module.new {
...
}
end

Not quite as elegant since we can't use do...end. But if #extend could
take a block:

class X
extend do
...
end
end

Then the issue becomes transparent. Even for regular objects:

obj.extend do
...
end

I like this - how do you see it working alongside the proposed
#class_extension from a while ago?

I guess #extend would work as above (i.e. defines singleton methods on
instances), where #class_extension (or #class_extend?) methods/modules
would both extend a class and be inherited by subclasses. I forget
where the discussions on module inheritance ended up. Would you have a
#module_extend method too or would #class_extension work for both
classes and modules (in which case it should be renamed or alased)?
This is not to say that a singleton_class/eigenclass method would never
be of use, but it would certainly mitigate the need for it a great deal.
(One might also take away from this that a better name for it, if it
were given a method name, would be #extension, but I mention that only
as an aside.)

I think you're onto something here - conceptually, #extend, singleton
methods and the-class-that-cannot-be-named are closely related but you
wouldn't know that from their names (or lack of them).

Perhaps #extension_class?

Regards,
Sean
 
D

David A. Black

Hi --

I like this - how do you see it working alongside the proposed
#class_extension from a while ago?

I guess #extend would work as above (i.e. defines singleton methods on
instances), where #class_extension (or #class_extend?) methods/modules
would both extend a class and be inherited by subclasses. I forget

I wouldn't want to see 'extend' start to mean both adding a module to
the lookup path, and adding methods to the singleton class, depending
on the context. I guess obj.extend do ... could create an anonymous
module, though I've never had an issue with just creating it with
Module.new or using a named module.
where the discussions on module inheritance ended up. Would you have a
#module_extend method too or would #class_extension work for both
classes and modules (in which case it should be renamed or alased)?


I think you're onto something here - conceptually, #extend, singleton
methods and the-class-that-cannot-be-named are closely related but you
wouldn't know that from their names (or lack of them).

They're related conceptually but they also fit into the object model
nicely: every method is defined in a class or module; every object has
a lookup path of classes and modules. I know Matz has said that the
main thrust of per-object behavior is per-object behavior, and that
the way it's implemented (singleton class, which, like other classes,
can include modules) is secondary, but there's a tremendous advantage
to having it blend into the overall landscape, I think. I've seen
literally hundreds of "Ah ha!" moments where people suddenly grasp the
whole per-object thing because once you get the idea of every object
having a singleton class, you don't have to learn anything else new
(with regard to #extend, etc.).


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
R

Robert Dober

module Kernel
alias_method :__extend__, :extend
def extend mod=nil, &blk
__extend__( mod || Module::new( &blk ) )
self
end
end

class A
extend do
def a;42 end
end
end

a = Object::new.extend do
def b; 49 end
end
I believe that these things are better done to your own taste and
shell not make the core larger as it is already, because there simply
is no account for taste.

HTH
Robert
 
S

Sean O'Halpin

They're related conceptually but they also fit into the object model
nicely: every method is defined in a class or module; every object has
a lookup path of classes and modules. I know Matz has said that the
main thrust of per-object behavior is per-object behavior, and that
the way it's implemented (singleton class, which, like other classes,
can include modules) is secondary, but there's a tremendous advantage
to having it blend into the overall landscape

I agree. After all, subclasses lookup class methods in a parent
class's singleton class and clones inherit from an instance's, e.g.

class A
def self.foo
"foo"
end
end
class B < A
end
a = A.new
def a.foo
"bar"
end
b = a.clone
puts B.foo
puts b.foo

# >> foo
# >> bar

That is hardly secondary behaviour. We can access an instance's class
by name (via object.class) - why not the singleton (or extension)
class?
I think. I've seen
literally hundreds of "Ah ha!" moments where people suddenly grasp the
whole per-object thing because once you get the idea of every object
having a singleton class, you don't have to learn anything else new
(with regard to #extend, etc.).

Well, not hundreds in my case, but it's definitely one of those
epiphany moments (along with 'classes are objects too'). I think
naming the elements involved similarly (extend, extension_class,
extension_methods, etc.) would help clarify the relationship between
these concepts.

(As an aside - why is there no method #extended_modules analogous to
#included_modules?)

Regards,
Sean
 
D

David A. Black

Hi --

I agree. After all, subclasses lookup class methods in a parent
class's singleton class and clones inherit from an instance's, e.g.

class A
def self.foo
"foo"
end
end
class B < A
end
a = A.new
def a.foo
"bar"
end
b = a.clone
puts B.foo
puts b.foo

# >> foo
# >> bar

That is hardly secondary behaviour. We can access an instance's class
by name (via object.class) - why not the singleton (or extension)
class?


Well, not hundreds in my case, but it's definitely one of those
epiphany moments (along with 'classes are objects too'). I think
naming the elements involved similarly (extend, extension_class,
extension_methods, etc.) would help clarify the relationship between
these concepts.

But 'extend' already means something: add a module to the lookup path.
The module that gets added is a completely different object from the
singleton class, and you can extend an object with any number of
modules, anonymous or otherwise. So there's no special identity
between the 'extend' operation and the singleton class. There's a
relation, in the sense that obj.extend(M) is like class << obj;
include M; end, but I don't think there's any reason to name the
singleton class itself in honor of the fact that there's a method
called extend that operates on it, if you see what I mean.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
S

Sean O'Halpin

[snip]
But 'extend' already means something: add a module to the lookup path.

Yes - to the special lookup path shared by subclasses qua instances and clones.
The module that gets added is a completely different object from the
singleton class, and you can extend an object with any number of
modules, anonymous or otherwise.

Well, yes, that's understood :)
So there's no special identity
between the 'extend' operation and the singleton class.

I'm not saying there's an identity - I'm saying that extend and the
singleton class are closely related concepts.
There's a
relation, in the sense that obj.extend(M) is like class << obj;
include M; end, but I don't think there's any reason to name the
singleton class itself in honor of the fact that there's a method
called extend that operates on it, if you see what I mean.

I do see what you mean. However, the relationship between #extend and
the singleton class
is much closer than you allow. The singleton class is the thing that's
extended. There are no
other methods that operate exclusively on the singleton class. In
fact, the singleton class springs
into existence to accommodate an extend if it's not already there.

On reading Trans' post, I was struck that extension_class, i.e. the
site of extensions, would be a good name to unify these concepts.
But I'd be happy with any name.

Regards,
Sean
 
T

Thomas Sawyer

David said:
I wouldn't want to see 'extend' start to mean both adding a module to
the lookup path, and adding methods to the singleton class, depending
on the context. I guess obj.extend do ... could create an anonymous
module, though I've never had an issue with just creating it with
Module.new or using a named module.

Ah, sorry I wasn't more clear. Yes, I meant it would create an anonymous
module, so as to promote good coding practices. And I agree, it isn't
that hard to use Module.new or name the module, nevertheless we see the
singleton being used directly far too often b/c it is more convenient,
even when having to define our own #singleton_method. And that's the
point of the suggestion, to make it more convenient to #extend rather
than #class_eval on the singleton class. Indeed (I wish I could find
that article) one can make a good case that the singleton class should
never have methods directly defined in it; always use a module.

T.
 
T

Thomas Sawyer

Sean said:
[snip]

I like this - how do you see it working alongside the proposed
#class_extension from a while ago?

I guess #extend would work as above (i.e. defines singleton methods on
instances), where #class_extension (or #class_extend?) methods/modules
would both extend a class and be inherited by subclasses. I forget
where the discussions on module inheritance ended up. Would you have a
#module_extend method too or would #class_extension work for both
classes and modules (in which case it should be renamed or alased)?

Hey, that's a really good point. #class_extension is very much the same
thing, but specifically designed to allow classes to carry the modules
behavior through the class-level hierarchy. So accordingly a better name
would be #class_extend. But as with the original, I still think that
this doesn't convey enough of what it actually does to the inheritance
chain, and likewise why #module_extend doesn't really make sense. But a
concise name for #extend_and _propogate_through_the_class_hierarchy
seems elusive.
I think you're onto something here - conceptually, #extend, singleton
methods and the-class-that-cannot-be-named are closely related but you
wouldn't know that from their names (or lack of them).

Perhaps #extension_class?

My goodness, when you put it like that it does seem rather obvious. I
wonder why no one has ever thought of that before.

T.
 
D

David A. Black

Hi --

[snip]
But 'extend' already means something: add a module to the lookup path.

Yes - to the special lookup path shared by subclasses qua instances and clones.

I'm not sure what you mean by special. Every object has only one
lookup path, and the singleton class is just placed along that path.
Do you mean the special class of singleton classes of class objects?
(The thing where their subclasses share the singleton methods.)
Well, yes, that's understood :)


I'm not saying there's an identity - I'm saying that extend and the
singleton class are closely related concepts.

Yes, but singleton class and non-singleton class are also closely
related. So are class and module, array and hash, integer and float...
but I wouldn't merge their terminology :)
I do see what you mean. However, the relationship between #extend and
the singleton class
is much closer than you allow. The singleton class is the thing that's
extended. There are no
other methods that operate exclusively on the singleton class. In
fact, the singleton class springs
into existence to accommodate an extend if it's not already there.

But I wouldn't want to rename Class to IncludeClass, just because
there's an include operation especially designed for classes. I know
there's a bit more going on than that: the idea of "extending" an
object's capabilities is always present, in some form, with all this
per-object behavior in some form. But since there's already an #extend
method, I think the term is potentially too flattening, so to speak.
I'd like to be able to refer to the singleton class without seeming to
refer to the process of including modules in it, which may or may not
happen (via extend or include).
On reading Trans' post, I was struck that extension_class, i.e. the
site of extensions, would be a good name to unify these concepts.
But I'd be happy with any name.

With the disclaimer that I consider there not to be a naming problem
(except for the question of whether 'singleton class' is the right
name in the class of Class objects, which grant singleton class access
to their subclass objects), I'm starting to think of 'e_class'.
Extension, extra, eigen... it's a duck-typed name :)


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
D

David A. Black

Hi --

Ah, sorry I wasn't more clear. Yes, I meant it would create an anonymous
module, so as to promote good coding practices. And I agree, it isn't
that hard to use Module.new or name the module, nevertheless we see the
singleton being used directly far too often b/c it is more convenient,
even when having to define our own #singleton_method. And that's the
point of the suggestion, to make it more convenient to #extend rather
than #class_eval on the singleton class. Indeed (I wish I could find
that article) one can make a good case that the singleton class should
never have methods directly defined in it; always use a module.

I'd be interested in seeing that article if you can find it. It
doesn't strike me right off as a convincing idea, but the reasoning
would be interesting to see.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 
R

Robert Dober

Ah, sorry I wasn't more clear. Yes, I meant it would create an anonymous
module, so as to promote good coding practices. And I agree, it isn't
that hard to use Module.new or name the module, nevertheless we see the
singleton being used directly far too often b/c it is more convenient,
even when having to define our own #singleton_method. And that's the
point of the suggestion, to make it more convenient to #extend rather
than #class_eval on the singleton class. Indeed (I wish I could find
that article) one can make a good case that the singleton class should
never have methods directly defined in it; always use a module.
Too bad you cannot find the article. I wonder especially if the
rationale behind that "dogma" was based on performance ( hopefully not
) or design principles.

Cheers
R.
 
D

David A. Black

Hi --


I think it's very good advice for many situations (#extend has always
been my favorite technique for changing the behavior of core objects,
for example). I don't think it's necessary, though, to choose one over
the other in an exclusive sense. This doesn't bother me:

class C
class << self
def x
end

def y
end
end
end

etc. Jay's example with extending an object with two modules, so that
the most recent one "wins" (whereas all modules "lose" if the method
in question is defined in the singleton class) is very convincing,
though again I wouldn't necessarily treat it as a reason never to
define a method in the singleton class. I'd say it's more that you
want to know what the ramifications of each technique are, and then
choose the one you want. In that sense it's analogous (though not
identical) to the non-singleton case, where a method defined in a
class "wins", for the instances of the class, over definitions in
included modules. That can be good, or not; it depends on what you're
trying to do.

It all comes down to mastery of the order of method lookup, which then
allows you to do pretty much any permutation.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!
 

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,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top