Submitted by itsme213 (Sat Apr 17 03:04:28 UTC 2004)
Say I have classes A1, A2,...An. Sometimes one subset of these classes has one set of shared behaviors: say A1, A2, A3 share m1(), m2().
Perhaps another subset share different behaviors: say A2, A5, A7 share n1(), n2().
Extracting this commonality using Ruby's single inheritance is difficult. Extracting it using a module can take quite a lot of refactoring work; this may be a worthwhile only if that module will be widely reused later.
The alternative is code duplication
class A1, A2, A3 def m1 ... def m2 ... end class A2, A5, A7 def n1 ... def n2 ... end
class A1, A2, A3 = CL_123 def ... end
class X include CL_123 end # approx. same as including X in the original CL_123 class list: A1, A2, A3, X
This borrows the approach used in CSS: no explicit class-like inheritance. You simply list all the selectors that you want to share a common set of stylings.
E1, E2, E3 {
display: block;
}
This might also encourage more classes to be defined in this incremental style, which brings its own pros/cons.
class A, B
common_body
endcan translate roughly into:
class A
common_body
end class B
common_body
end
... although I am not sure that side effects should occur twice.
The optional second and third parts of the proposal may be implementable by:
class A, B = C_AB
ab_body
end
translates into:
class C_AB
ab_body
end
C_AB.freeze
class A, B
include C_AB
end
Including a class in another class behaves like textual insertion of the included class body. Again, I'm not sure if it might be better to carry the original context along e.g. closures.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
You seem to be suggesting that:
is just a lengthy way of writing which it isn't. In the first example you have two different methods (both called x). In the second example you have ONE method, present in the method search path of two classes.It's not clear which case you're addressing, since you present them as interchangeable. Also, in your implementation, you're doing "include C" where C is a class. (That won't work.) In general this seems to be a kind of parallel-universe Ruby, where things don't work quite as they do in Ruby and therefore have to be fixed. I think you'll find that Class and Module objects do what you need quite elegantly.
-- David Black
You say "Extracting it using a module can take quite a lot of refactoring work; this may be a worthwhile only if that module will be widely reused later."
I don't see why
is better than
plus include Foo.I believe your reasoning is flawed: you're comparing
and module on different basis; you seem to consider when you know already some implementation will be shared amongst different classes, and module only when you realize this _afterwards_.The similariry of your 'classlets' to regular modules is even more striking when one reads the 2nd and 3rd (optional) proposals.
is very, very similar toPlease tell me if I missed the point completely.
-- Mauricio Fernández