# Instead of templates

**URL:** <https://rubytalk.org/t/instead-of-templates/17149>\
**Category:** ruby-talk\
**Created:** [24 March 2005 11:15 UTC](https://rubytalk.org/t/instead-of-templates/17149 "2005-03-24T11:15:49Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adelle\_Hartley](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@Adelle\_Hartley](https://rubytalk.org/u/Adelle_Hartley)\
**Post date:** [24 March 2005 11:15 UTC](https://rubytalk.org/t/instead-of-templates/17149/1 "2005-03-24T11:15:49Z")

</div>

Hi all,

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

&nbsp;&nbsp;class A \<\< MyBaseClass  
&nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;class B \<\< MyBaseClass  
&nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;class C \<\< B  
&nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

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

Adelle.

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [24 March 2005 11:24 UTC](https://rubytalk.org/t/instead-of-templates/17149/2 "2005-03-24T11:24:53Z")

</div>

"Adelle Hartley" \<adelle@bullet.net.au\> schrieb im Newsbeitrag  
news:courier.4242A14D.00002361@mars.sisgroup.com.au...

> Hi all,
> 
> I have some methods that I want to add to several classes.  
> eg.
> 
> &nbsp;&nbsp;class A \<\< MyBaseClass  
> &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;class B \<\< MyBaseClass  
> &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;class C \<\< B  
> &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> If I were writing this in C++, I'd use templates. What's the Ruby Way?

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

&nbsp;&nbsp;def do\_my\_thing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;# whatever  
&nbsp;&nbsp;&nbsp;&nbsp;p klass  
&nbsp;&nbsp;end  
end

> > class A  
> > &nbsp;&nbsp;extend Extension  
> > end

=\> A

> > A.do\_my\_thing

A  
=\> nil

> > class B \< A  
> > end

=\> nil

> > B.do\_my\_thing

B  
=\> nil

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<div class="post-metadata">

**Author:** ![gabriele\_renzi5](https://avatars.discourse-cdn.com/v4/letter/g/e79b87/32.png) [@gabriele\_renzi5](https://rubytalk.org/u/gabriele_renzi5)\
**Post date:** [24 March 2005 11:34 UTC](https://rubytalk.org/t/instead-of-templates/17149/3 "2005-03-24T11:34:49Z")

</div>

Adelle Hartley ha scritto:

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

probably mixins using #extend :  
\>\> a=Class.new  
=\> #\<Class:0x2be5788\>  
\>\> module M; def foo() 'yuk' end; end  
=\> nil  
\>\> a.extend M  
=\> #\<Class:0x2be5788\>  
\>\> a.foo  
=\> "yuk"

---

<div class="post-metadata">

**Author:** ![Mathieu\_Bouchard1](https://avatars.discourse-cdn.com/v4/letter/m/3da27b/32.png) [@Mathieu\_Bouchard1](https://rubytalk.org/u/Mathieu_Bouchard1)\
**Post date:** [26 March 2005 03:02 UTC](https://rubytalk.org/t/instead-of-templates/17149/4 "2005-03-26T03:02:29Z")

</div>

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:

&nbsp;&nbsp;List.of(Float)

or

&nbsp;&nbsp;List[Float]

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

e.g.:

class A  
&nbsp;&nbsp;@special={}  
&nbsp;&nbsp;def self.of(t)  
&nbsp;&nbsp;&nbsp;&nbsp;@special[t] ||= Class.new(self) { @mytype=t; ... }  
&nbsp;&nbsp;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?

> **···**
>
> On Thu, 24 Mar 2005, Adelle Hartley wrote:
> 
> > &nbsp;&nbsp;class A \<\< MyBaseClass  
> > &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;class B \<\< MyBaseClass  
> > &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;class C \<\< B  
> > &nbsp;&nbsp;&nbsp;&nbsp;def self.DoMyThing(klass=self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end  
> > If I were writing this in C++, I'd use templates. What's the Ruby Way?
> 
> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> Mathieu Bouchard -=- Montréal QC Canada -=- [http://artengine.ca/matju](http://artengine.ca/matju)

---

<div class="post-metadata">

**Author:** ![Adelle\_Hartley](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@Adelle\_Hartley](https://rubytalk.org/u/Adelle_Hartley)\
**Post date:** [24 March 2005 15:12 UTC](https://rubytalk.org/t/instead-of-templates/17149/5 "2005-03-24T15:12:32Z")

</div>

Hi,

> \>  
> \> If I were writing this in C++, I'd use templates. What's  
> the Ruby Way?
> 
> module Extension  
> &nbsp;&nbsp;# this one is really only neede if you  
> &nbsp;&nbsp;# want to inherit this behavior automatically  
> &nbsp;&nbsp;# down the class hierarchy  
> &nbsp;&nbsp;def inherited(cl)  
> &nbsp;&nbsp;&nbsp;&nbsp;cl.extend Extension  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def do\_my\_thing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;# whatever  
> &nbsp;&nbsp;&nbsp;&nbsp;p klass  
> &nbsp;&nbsp;end  
> end
> 
> \>\> class A  
> \>\> extend Extension  
> \>\> end

Close, but no banana.

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

class MyBase  
&nbsp;&nbsp;def self.do\_my\_thing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;p '-----'  
&nbsp;&nbsp;end  
end

module Extension  
&nbsp;&nbsp;def inherited(cl)  
&nbsp;&nbsp;&nbsp;&nbsp;cl.extend Extension  
&nbsp;&nbsp;end

&nbsp;&nbsp;def do\_my\_thing(klass=self)  
&nbsp;&nbsp;&nbsp;&nbsp;p klass  
&nbsp;&nbsp;&nbsp;&nbsp;super(klass.superclass)  
&nbsp;&nbsp;end  
end

class A \< MyBase  
&nbsp;&nbsp;&nbsp;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.

---

<div class="post-metadata">

**Author:** ![Adelle\_Hartley](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@Adelle\_Hartley](https://rubytalk.org/u/Adelle_Hartley)\
**Post date:** [26 March 2005 09:42 UTC](https://rubytalk.org/t/instead-of-templates/17149/6 "2005-03-26T09:42:54Z")

</div>

Hi Mathieu,

> class A  
> &nbsp;&nbsp;@special={}  
> &nbsp;&nbsp;def self.of(t)  
> &nbsp;&nbsp;&nbsp;&nbsp;@special[t] ||= Class.new(self) { @mytype=t; ... }  
> &nbsp;&nbsp;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.

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [24 March 2005 16:29 UTC](https://rubytalk.org/t/instead-of-templates/17149/7 "2005-03-24T16:29:57Z")

</div>

"Adelle Hartley" \<adelle@bullet.net.au\> schrieb im Newsbeitrag  
news:courier.4242D8BE.000002FE@mars.sisgroup.com.au...

> Hi,
> 
> \> \>  
> \> \> 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  
> \>  
> \> \>\> class A  
> \> \>\> extend Extension  
> \> \>\> end
> 
> 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  
> &nbsp;&nbsp;def self.do\_my\_thing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;p '-----'  
> &nbsp;&nbsp;end  
> end
> 
> module Extension  
> &nbsp;&nbsp;def inherited(cl)  
> &nbsp;&nbsp;&nbsp;&nbsp;cl.extend Extension  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def do\_my\_thing(klass=self)  
> &nbsp;&nbsp;&nbsp;&nbsp;p klass

&nbsp;&nbsp;&nbsp;&nbsp;superclass.do\_my\_thing

> &nbsp;&nbsp;end  
> end
> 
> class A \< MyBase  
> &nbsp;&nbsp;&nbsp;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

&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<div class="post-metadata">

**Author:** ![Adelle\_Hartley](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@Adelle\_Hartley](https://rubytalk.org/u/Adelle_Hartley)\
**Post date:** [25 March 2005 01:46 UTC](https://rubytalk.org/t/instead-of-templates/17149/8 "2005-03-25T01:46:33Z")

</div>

Robert Klemme wrote:

> 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
> 
> &nbsp;&nbsp;&nbsp;&nbsp;superclass.do\_my\_thing
> 
> \> end  
> \> end  
> \>

\<snip\>

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

---

<div class="post-metadata">

**Author:** ![Adelle\_Hartley](https://avatars.discourse-cdn.com/v4/letter/a/8e7dd6/32.png) [@Adelle\_Hartley](https://rubytalk.org/u/Adelle_Hartley)\
**Post date:** [26 March 2005 10:29 UTC](https://rubytalk.org/t/instead-of-templates/17149/9 "2005-03-26T10:29:12Z")

</div>

ARggh.

> \> \> 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

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

Adelle.

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [26 March 2005 17:24 UTC](https://rubytalk.org/t/instead-of-templates/17149/10 "2005-03-26T17:24:47Z")

</div>

"Adelle Hartley" \<adelle@bullet.net.au\> schrieb im Newsbeitrag news:courier.42453960.00006AA7@mars.sisgroup.com.au...

> ARggh.
> 
> > \> \> 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
> 
> 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:

> > module Foo; def bar() "bar" end end

=\> nil

> > class A  
> > include Foo  
> > end

=\> A

> > class B \< A  
> > end

=\> nil

> > B.new.bar

=\> "bar"

Cheers

&nbsp;&nbsp;&nbsp;&nbsp;robert
