Robert Klemme
3/13/2008 10:18:00 PM
On 13.03.2008 20:35, ara howard wrote:
> On Mar 12, 2008, at 7:14 PM, Trans wrote:
>
>> Which approach is better: parametric module or an injecting class
>> method.
>
> i would say neither and both. it's saner to decouple them and then
> recouple - giving the best of both worlds with the same amount of code:
>
>
> cfp2:~ > cat a.rb
> module Equate
> module Methods
> def equate a, b
> module_eval <<-code
> def ==(other)
> self.#{ a } == other.#{ a } && self.#{ b } == other.#{ b }
> end
> def eql?(other)
> self.#{ a }.eql?(other.#{ a }) && self.#{ b }.eql?
> (other.#{ b })
> end
> def hash()
> self.#{ a }.hash ^ self.#{ b }.hash
> end
> code
> end
> end
>
> def Equate.included other
> other.send :extend, Methods
> end
>
> def Equate.on a, b
> Module.new{
> include Equate
> equate a, b
> }
> end
> end
>
> class C < Struct.new(:a, :b)
> include Equate.on(:a, :b)
> end
>
> p C[4,2] == C[4,2] #=> true
> p C[4,2] == C[4,3] #=> false
>
> class D < Struct.new(:a, :b)
> include Equate
> equate :a, :b
> end
>
> p D[4,2] == D[4,2] #=> true
> p D[4,2] == D[4,3] #=> false
>
>
>
> cfp2:~ > ruby a.rb
> true
> false
> true
> false
Using a Struct generated class as base class is a bad example IMHO
because those classes do already have the equation properties.
At the moment the only advantage I see in using modules is avoidance of
namespace pollution. Personally I'd just have a method in class Module
equate_on which defines methods as shown.
Btw, while we're at it, I'd also like order_on which defines <=> based
on fields given. :-)
Kind regards
robert