Subclassing Class


#1

Ok. This is a wild idea.

I don’t like the factory pattern.

We don’t need no stinkin Factories. We have the Class object.

All a Factory is really Class.

However, a traditional Factory object can have…

  • State.
  • Richer behaviour than the Class class.

Ok, this gets a little hairy so lets get concrete.

class Foo
end

fo = Foo.new

What is the class of fo? Foo

What is the class of Foo? Class

Now a FooFactory object is just an object with a bit more intelligence
and state that the traditional Foo class object for making Foo
instances in a better smarter way.

So the obvious thing to do is instead of making a new class FooFactory
< Object, it should inherit from Class.

Well, since Foo is already a Class, we really just want a smarter Class.

ie…

Instead of

class FooFactory
def initialize( foo_state)
@foo_state = foo_state
end

def foo_fu( bah)
# Knowledge of Foo making
end

def create( needs_fu, stuff)
Foo.new( foo_fu( needs_fu), @foo_state, stuff)
end
end

factory = FooFactory.new( ‘foo juice’)
foo = factory.create( ‘footile’)

We really want

class Foo < Class
def initialize( foo_state)
@foo_state = foo_state
end

def foo_fu( bah)
# Knowledge of Foo making
end

def new( needs_fu, stuff)
super( foo_fu( needs_fu), @foo_state, stuff)
end
end

foo = Foo.new( ‘fooless’, ‘stuffed’)

Except ruby doesn’t like that
class Foo < Class
bit.

It gets quite grumpy in fact.

Ruby says “can’t make subclass of Class (TypeError)”

Rats.

We can however say…

FooClass = Class.new(Class)

Unfortunately we can’t then say…

FooClass.new( Object)

Ruby says…
:in `new’: wrong instance allocation (TypeError)

Ahh! I’m just going around in circles fighting Ruby.

We need a way of saying…

class FooClass < Class

Add state and behaviour to Class

end

And then instead of saying…
class Foo < FooParent
# Add state and behaviour to FooParent
end
we need to be able to say…

FooClass Foo < FooParent

Add state and behaviour to FooParent

end

Aargh! I’m chasing my tail.

Is there anyway, (short of the traditional Factory Pattern) for me to
catch my tail?

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.


#2

bit.

It gets quite grumpy in fact.

Ruby says “can’t make subclass of Class (TypeError)”

Yes, there is a way: Singleton classes or “eigenclasses”:

class Foo
def self.new(needs_fu, stuff) # Could be Foo.new, too, but self keeps
us warm and DRY.
super(foo_fu(needs_fu), @foo_state, stuff)
end
end

Each Class (and indeed, every other object) has its own private class,
for just that object alone, the eigenclass. It can have methods added to
with the def instance.method syntax – self.new, in this case, or
Foo.new would work just as well – and so, Foo.new is different than
another class’s new method. Since it’s a “virtual” child class of Class,
it works as you’d expect with regards to super.

Aria


#3

On Dec 5, 2005, at 7:57 PM, John C. wrote:

  • Richer behaviour than the Class class.
    What is the class of Foo? Class
    Class.
    def foo_fu( bah)

bit.

FooClass Foo < FooParent
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly
wrong later.”

From this principle, all of life and physics may be deduced.

Why are you trying so hard?

class Foo
# state and behavior for Foo the Class
# using class instance variables and singleton methods

eg:

@foo_state = foo_state # this works believe it or not

etc.

@old_new = method(:new)
def self.new(needs_fi, stuff)
@old_new.call(foo_fu(needs_fu, @foo_state, stuff)
end
end

What does subclassing class get you over this approach? Your class
can be your factory (in ruby anyway).


#4

Yes, there is a way: Singleton classes or “eigenclasses”.

In this context it is generally called the metaclass. But I’m really
digging this new “adhoc”. As in, “He completely rewrote the method
adhoc.”

BTW, factories come into play when the class of the object instantiated
is unknown. I don’t see that. It looks like you (John) are talking more
about alternate instantation signitures --but maybe I’ve overlooked
something in what you said. Nonetheless, it is true that a class method
(class methods are adhoc) can be used in either case.

T.


#5

Hi –

On Tue, 6 Dec 2005, Aredridel wrote:

Each Class (and indeed, every other object) has its own private class,
for just that object alone, the eigenclass. It can have methods added to
^^^^^^^^^^

Is there any chance of stemming the tide of nicknames and coined
synonyms
for singleton classes? Or may I at least put in a plea for flagging
them
as nicknames and coinages? I know there’s a kind of ongoing discussion
about what the best eventual official name might be, if “singleton
class”
is ever replaced, but I think that having a lot of unofficial/unflagged
names in circulation is potentially very confusing and therefore
probably
not an ideal interim measure.

David
__
David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


#6

John C. ha scritto:

Ok. This is a wild idea.

I don’t like the factory pattern.

We don’t need no stinkin Factories. We have the Class object.

given that people already told you about overriding Class#new, I won’t
replicate.
But I wonder what is the problem you’re tying to solve, if you just want
to add state and behaviour to an object, maybe you could just
include/extend a module?


#7

On Tue, 6 Dec 2005, gabriele renzi wrote:

John C. ha scritto:

Ok. This is a wild idea.

I don’t like the factory pattern.

We don’t need no stinkin Factories. We have the Class object.

But I wonder what is the problem you’re tying to solve, if you just want to
add state and behaviour to an object, maybe you could just include/extend a
module?

Add state and polymorphic behaviour, not to the object, but the
object’s class. And that is where the wheels fall off.

@@variables give classes state.

ClassName.method_name functions given classes behaviour.

But it is all static, no polymorphism.

(Perhaps I should have called it the factory method pattern. When I
tried
to find a definitive answer on that I find I’m certainly not alone in
stirring that particular pot of confusion…)

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.


#8

On Tue, 6 Dec 2005, Aredridel wrote:

class Foo
def self.new(needs_fu, stuff) # Could be Foo.new, too, but self keeps
us warm and DRY.
super(foo_fu(needs_fu), @foo_state, stuff)
end
end

Each Class (and indeed, every other object) has its own private class,
for just that object alone, the eigenclass. It can have methods added to
with the def instance.method syntax – self.new, in this case, or
Foo.new would work just as well – and so, Foo.new is different than
another class’s new method. Since it’s a “virtual” child class of Class,
it works as you’d expect with regards to super.

Err. Right.

On to the next step. Let’s rename Foo to AbstractFoo

Now I wanted
class AbstractFoo < Class
end

and you have given me that. But that was merely the first step in my
agenda.

I actually also want…
class ConcreteFooClass < AbstractFooClass
end

class OtherConcreteFooClass < AbstractFooClass
end
that polymorphically inherits behaviour from AbstractFooClass.

I’m starting to really hate the Builder, Factory, AbstractFactory,
FactoryMethod names. They are not explicit enough to distinguish which
is
what from the name, and the web seems to pretty confused on the subject
as well. Anyhoo, factory method pattern is what trying to do.

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.


#9

Hi –

On Tue, 6 Dec 2005, John C. wrote:

Hmm. It’s perfectly standard mathematical terminology for an operator A,
if you can find a limited subset of items e_i such that A operating on
item e_i results in the same item e_i (upto a scalar factor), then
the e_i are called an eigenstate of the operator A and the scalar factor
is the eigenvalue.

This usage of the term “eigen” is far far wider than ruby and far far
older.

So are thousands of other usages of “eigen” :slight_smile: But I’m not arguing for
or against ‘eigenclass’. I’m just suggesting that we not enter an era

or, rather that we leave the era we appear to have entered – of using a
variety of unofficial names for singleton classes as if they were the
official name.

If this usage maps in some fairly clear manner onto singleton classes then
clearly the term singleton class should be dropped in favour of
eigenclass.

The question then is “Is there an operation which leaves the singleton
classes, and only the singleton classes, unaltered (except perhaps in some
trivial fashion)?”

“Eigen” is actually a much more common and adaptable term than that.
It’s basically German for “own”, and appears all over the place in
compounds and as a prefix (Eigentum is property (stuff you own),
Eigenschaft is a property (in the sense of a characteristic), etc.).

No particular antecedent coinage has a claim on Ruby’s loyalty. If it’s
a
good replacement for “singleton class”, it’s because of what “eigen” +
“class” suggests in its own right.

David
__
David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


#10

Hi John,

I’m starting to really hate the Builder, Factory, AbstractFactory,
FactoryMethod names. They are not explicit enough to distinguish which is
what from the name

I agree with you. I once heard Eric Evans (author of the best
technical book I’ve ever read, “Domain Driven Design”) remark that he
thought the GoF “Factory Method” should be called “Polymorphic
Factory” and “Abstract Factory” should be “Family Factory”. Eric’s
names make a lot of sense to me.

Wayne V.
No Bugs Software
“Ruby and C++ Agile Contract Programming in Silicon Valley”


#11

On Tue, 6 Dec 2005, David A. Black wrote:

On Tue, 6 Dec 2005, Aredridel wrote:

Each Class (and indeed, every other object) has its own private class,
for just that object alone, the eigenclass. It can have methods added to
^^^^^^^^^^

Is there any chance of stemming the tide of nicknames and coined synonyms
for singleton classes?

Hmm. It’s perfectly standard mathematical terminology for an operator A,
if you can find a limited subset of items e_i such that A operating on
item e_i results in the same item e_i (upto a scalar factor), then
the e_i are called an eigenstate of the operator A and the scalar factor
is the eigenvalue.

This usage of the term “eigen” is far far wider than ruby and far far
older.

If this usage maps in some fairly clear manner onto singleton classes
then
clearly the term singleton class should be dropped in favour of
eigenclass.

The question then is “Is there an operation which leaves the singleton
classes, and only the singleton classes, unaltered (except perhaps in
some
trivial fashion)?”

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand

Carter’s Clarification of Murphy’s Law.

“Things only ever go right so that they may go more spectacularly wrong
later.”

From this principle, all of life and physics may be deduced.


#12

John C. schrieb:

I actually also want…
class ConcreteFooClass < AbstractFooClass
end

class OtherConcreteFooClass < AbstractFooClass
end
that polymorphically inherits behaviour from AbstractFooClass.

John, I’m not sure what you really need, but I think that the singleton
class approach that others have suggested gives you the desired
behaviour:

class Foo
def self.new fu, stuff
super “#{fu} and #{stuff}”
end
def initialize things
puts “new Foo with #{things}”
end
end

Foo.new “abstract fu”, “abstract stuff”

=> new Foo with abstract fu and abstract stuff

class ConcreteFoo < Foo
def self.new fu
super fu, “concrete stuff”
end
def initialize things
print "ConcreteFoo: "
super
end
end

ConcreteFoo.new “concrete fu”

=> ConcreteFoo: new Foo with concrete fu and concrete stuff

The class ConcreteFoo inherits behaviour from the class Foo and
ConcreteFoo’s singleton class inherits from Foo’s singleton class.

I don’t know whether this still works in Ruby 1.9, though.

Regards,
Pit


#13

On Tue, 06 Dec 2005 03:36:21 -0000, David A. Black removed_email_address@domain.invalid
wrote:

No particular antecedent coinage has a claim on Ruby’s loyalty. If it’s
a
good replacement for “singleton class”, it’s because of what “eigen” +
“class” suggests in its own right.

Absolutely. Which I would suggest is ‘very little’, if only because
there
are so many and varied (and often technical) uses already for ‘eigen’.
‘Singleton class’ has a kind-of-correctness about it I think which puts
the newbie on the right track. I’m not advocating sticking with it, but
it
stripped away some mystique for me early on, and that kind of hint is
important…

Also strongly agree with your observations about the the current
situation

  • it was most confusing when I started out, and I know that a few others
    find the changeable terminology confusing. I believe that one official
    bad
    name has to be better than N unofficial ones regardless of quality or
    correctness.

#14

Ross B. schrieb:

new Foo with abstract fu and abstract stuff
ConcreteFoo: new Foo with concrete fu and concrete stuff

[rosco@jukebox ruby]$ ruby9 oneninetest.rb
new Foo with abstract fu and abstract stuff
ConcreteFoo: new Foo with concrete fu and concrete stuff

Thanks for the info, Ross. I remember vaguely that something about the
inheritance of classes’ singleton classes should change in Ruby 2, but
I’m not sure.

Regards,
Pit


#15

John C. removed_email_address@domain.invalid wrote:

clearly the term singleton class should be dropped in favour of
eigenclass.

The question then is “Is there an operation which leaves the singleton
classes, and only the singleton classes, unaltered (except perhaps in some
trivial fashion)?”

The mathematical usage draws on the German word for “own”, as does
“eigenclass”. It’s a lot less ambiguous a term than “singleton class”,
and the fact that it’s a pleasing and apt term is indicated by the
number of rubyists who implicitly vote by using it. I don’t think any
other term has caught on as well since people started expressing
dissatisfaction with the ambiguous nature of “singleton class” and
“metaclass”.

martin


#16

On Tue, 06 Dec 2005 08:30:43 -0000, Pit C. removed_email_address@domain.invalid
wrote:

The class ConcreteFoo inherits behaviour from the class Foo and
ConcreteFoo’s singleton class inherits from Foo’s singleton class.

I don’t know whether this still works in Ruby 1.9, though.

It seems to (as of a few days ago at least):

[rosco@jukebox ruby]$ ruby oneninetest.rb
new Foo with abstract fu and abstract stuff
ConcreteFoo: new Foo with concrete fu and concrete stuff

[rosco@jukebox ruby]$ ruby9 oneninetest.rb
new Foo with abstract fu and abstract stuff
ConcreteFoo: new Foo with concrete fu and concrete stuff


#17

Hi –

On Tue, 6 Dec 2005, Martin DeMello wrote:

If this usage maps in some fairly clear manner onto singleton classes then
number of rubyists who implicitly vote by using it.
A lot of the usage I’ve seen is from newcomers who see the term used by
non-newcomers and have no reason (because the situation is not explained
to them) to believe that it’s anything but the standard, official term.

I don’t think any other term has caught on as well since people started
expressing dissatisfaction with the ambiguous nature of “singleton
class” and “metaclass”.

That may be due to restraint on the part of people who prefer other
terms
than “eigenclass” but don’t think there should be a
“vote”-by-pre-emptive-usage contest in this area. I suppose I could
start
telling people that there’s a thing called the “own class” in Ruby (a
term
I’ve suggested) but I’ve chosen not to.

David
__
David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


#18

Hi –

On Wed, 7 Dec 2005 removed_email_address@domain.invalid wrote:

referenced and reused in another paper until they become part of the
standard nomenclature.

I know – I’ve done it myself. I’ve never hesitated to use neologisms
in
my own academic work, and if people find them helpful, they can use
them.
If not, they’re just something I came up with to help explain some
concept.

This is different. First of all, Ruby is a work by Matz, not any of us.
But, granting that single authorship is not really the whole story here,
there’s no vacuum for “eigen/virtual/meta/single/adhoc”-class to fill
anyway. There’s some fragility in the existing terms, but they do
exist,
and the fragility is being examined carefully by Matz with community
input. What is the benefit of short-circuiting that process?

And let’s say your model does apply. That means – as in common speech
and academic discourse – that different groups of people will use
different jargon for the same things. We’ll have the eigenclass people,
the metaclass people, and so on. And newcomers will have to learn about
all of them, so that they can talk to everyone.

I think, among other things, that there’s a limit to how tolerant people
are going to be of being expected to wallow in all this
meta-meta-culture.
It’s certainly not what attracted me to Ruby.

I do understand that new terms can be confusing and, unlike a refereed
paper, most posters don’t have footnotes to define all their terms, but
new terms will continue to emerge (e.g., Ajax) spontaneously.

The Ruby community is very fortunate to have Matz to sift through all
the suggestions, RCRs, code, and discussion and provide a certain amount
of guidance, but that doesn’t preclude other sources of inspiration (I
hope).

How about channeling these inspirations through the RCRs and
discussions? I just can’t see how throwing arbitrarily many home-made
synonyms for language-level constructs at newcomers can be of the
slightest benefit. In the short term I suppose it’s exhilerating and
makes people feel creative and participatory. But that’s

The big elephant in the room seems to be Matz comments that the
semantics of a meta/singleton/eigen class might be implemented via some
mechanism other than a class, which would certainly stir the pot a bit.

No elephant, from my perspective. That’s yet another reason (aside from
the general principle of respect for Matz’s unique role) for not having
the terminology free-for-all.

David
__
David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


#19

On Wed, 7 Dec 2005, David A. Black wrote:

How about channeling these inspirations through the RCRs and
discussions? I just can’t see how throwing arbitrarily many home-made
synonyms for language-level constructs at newcomers can be of the
slightest benefit. In the short term I suppose it’s exhilerating and
makes people feel creative and participatory. But that’s

…all he wrote? :slight_smile:

Oh, you know. Short-term, or some synonym for it :slight_smile:

David
__
David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


#20

On Dec 6, 2005, at 11:19 AM, David A. Black wrote:

This is different. First of all, Ruby is a work by Matz, not any
of us.

With all due respect to Matz, I think Ruby is now much more than the
work of a single person. Without a doubt, the community continues to
benefit from his leadership and there is no reason to think that that
won’t continue but let’s not pass over all the other contributors.

Gary W.