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