"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.
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
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?
···
On Thu, 24 Mar 2005, Adelle Hartley wrote:
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?
>
> 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:
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)?
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 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
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.
> 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
>
<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.
> > 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 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: