Instead of templates

A

Adelle Hartley

Hi all,

I have some methods that I want to add to several classes.
eg.

class A << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end

class B << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end

class C << B
def self.DoMyThing(klass=self)
...
end
end

If I were writing this in C++, I'd use templates. What's the Ruby Way?

Adelle.
 
R

Robert Klemme

Adelle Hartley said:
Hi all,

I have some methods that I want to add to several classes.
eg.

class A << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end

class B << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end

class C << B
def self.DoMyThing(klass=self)
...
end
end

If I were writing this in C++, I'd use templates. What's the Ruby Way?

module Extension
# this one is really only neede if you
# want to inherit this behavior automatically
# down the class hierarchy
def inherited(cl)
cl.extend Extension
end

def do_my_thing(klass=self)
# whatever
p klass
end
end
A
=> nilB
=> nil

Kind regards

robert
 
A

Adelle Hartley

Hi,
the Ruby Way?

module Extension
# this one is really only neede if you
# want to inherit this behavior automatically
# down the class hierarchy
def inherited(cl)
cl.extend Extension
end

def do_my_thing(klass=self)
# whatever
p klass
end
end

Close, but no banana.

Maybe I'm not doing it right. Here's what I've got:


class MyBase
def self.do_my_thing(klass=self)
p '-----'
end
end

module Extension
def inherited(cl)
cl.extend Extension
end

def do_my_thing(klass=self)
p klass
super(klass.superclass)
end
end

class A < MyBase
extend Extension
end

class B < A
end

class C < B
end

class D < C
end

D.do_my_thing



My output is:

D
"-----"


The output I want is:

D
C
B
A
"-----"


Is this possible (without repeating the definition of do_my_thing)?

Adelle.
 
R

Robert Klemme

Adelle Hartley said:
Hi,


Close, but no banana.

Maybe I'm not doing it right. Here's what I've got:

You cannot use super here, because super refers to the superclass of the
class instance. All class instances have the same super class hierarchy:
String.class.ancestors => [Class, Module, Object, Kernel]
Fixnum.class.ancestors
=> [Class, Module, Object, Kernel]

You need Class#superclass:
class MyBase
def self.do_my_thing(klass=self)
p '-----'
end
end

module Extension
def inherited(cl)
cl.extend Extension
end

def do_my_thing(klass=self)
p klass
superclass.do_my_thing

end
end

class A < MyBase
extend Extension
end

class B < A
end

class C < B
end

class D < C
end

D.do_my_thing



My output is:

D
"-----"


The output I want is:

D
C
B
A
"-----"


Is this possible (without repeating the definition of do_my_thing)?

And, btw, you don't need the class argument. You can print self instead.

?> D.do_my_thing
D
C
B
A
"-----"
=> nil

Kind regards

robert
 
A

Adelle Hartley

Robert said:
You cannot use super here, because super refers to the
superclass of the class instance. All class instances have
the same super class hierarchy:
String.class.ancestors => [Class, Module, Object, Kernel]
Fixnum.class.ancestors
=> [Class, Module, Object, Kernel]

You need Class#superclass:
class MyBase
def self.do_my_thing(klass=self)
p '-----'
end
end

module Extension
def inherited(cl)
cl.extend Extension
end

def do_my_thing(klass=self)
p klass
superclass.do_my_thing

end
end
And, btw, you don't need the class argument. You can print
self instead.

Fantastisch!! You have not only shown me how to do what I want but also how
to do it in a truly elegant way.

Adelle.
 
M

Mathieu Bouchard

class A << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end
class B << MyBaseClass
def self.DoMyThing(klass=self)
...
end
end
class C << B
def self.DoMyThing(klass=self)
...
end
end
If I were writing this in C++, I'd use templates. What's the Ruby Way?

I don't claim to represent the "Ruby Way", but personally I've done
similar things (in the RubyX11 project) that implement
parametrized-classes this way:

In each parametrized class, make a (class-wide) hash, and then create new
subclasses on-demand, remembering them in that hash. Then I may allow a
syntax like:

List.of(Float)

or

List[Float]

... as typenames, which get associated with an anonymous class that
subclasses my baseclass.

e.g.:

class A
@special={}
def self.of(t)
@special[t] ||= Class.new(self) { @mytype=t; ... }
end
end

Where "..." may be any specialisation-specific code, e.g. an eval that
recreates some methods in a speed-optimised way depending on t.

Does that make sense?

However I have no experience combining regular inheritance and this
technique, and I know this technique may be difficult to combine with
regular inheritance in a way that makes it really closer to C++.

Btw, what's the class A<<MyBaseClass syntax? AFAIK it's either class
A<MyBaseClass or class<<A. Is this a new syntax?

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju
 
A

Adelle Hartley

Hi Mathieu,
class A
@special={}
def self.of(t)
@special[t] ||= Class.new(self) { @mytype=t; ... }
end
end

That's a neat idea. I think I will keep that up my sleeve. I am bound to
need it.
Where "..." may be any specialisation-specific code, e.g. an
eval that recreates some methods in a speed-optimised way
depending on t.

Does that make sense?

However I have no experience combining regular inheritance
and this technique, and I know this technique may be
difficult to combine with regular inheritance in a way that
makes it really closer to C++.

Your technique already combines regular inheritance - all of your A.of(t)
classes inherit from A, so any method defined in A will be inherited by
A.of(t). My question (and Robert gave a good answer on how to do this) was
one degree more complicated because I not only wanted the child classes to
have their own implementation but wanted any classes that inherit from
*them* to have their own implementation as well.
Btw, what's the class A<<MyBaseClass syntax? AFAIK it's
either class A<MyBaseClass or class<<A. Is this a new syntax?

Heh, that's just air coding gone bad. << is not used for inheritance in
Ruby (AFAIK).

Adelle.
 
A

Adelle Hartley

ARggh.

This is pretty neat if I want to add class methods to child classes. Is
their an equivalent mechanism for adding instance methods?

Adelle.
 
R

Robert Klemme

Adelle Hartley said:
ARggh.


This is pretty neat if I want to add class methods to child classes. Is
their an equivalent mechanism for adding instance methods?

Not needed as they are inherited if you use "normal" module inclusion:
=> "bar"

Cheers

robert
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top