From: Robert Klemme Date: 2008-03-13T17:42:45+09:00 Subject: Re: Parametric module or injecting code via class method? 2008/3/13, Trans : > Which approach is better: parametric module or an injecting class > method. Are you writing a book on best practices? There seem to be quite a few of these questions recently. :-)) > # Generates identity/key methods based on specified attributes. > # > # include EquateOn(:a, :b) > # > # is equivalent to including a module containing: > # > # 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 > # > > def EquateOn(*fields) > code = "" > code << "def ==(o) " << fields.map {|f| "self.#{f} == > o.#{f}" }.join(" && ") << " end\n" > code << "def eql?(o) " << fields.map {|f| "self.#{f}.eql? > (o.#{f})" }.join(" && ") << " end\n" > code << "def hash() " << fields.map {|f| > "self.#{f}.hash" }.join(" ^ ") << " end\n" > mod = Module.new > mod.module_eval( code ) > mod > end > > - Or - > > # Generates identity/key methods based on specified attributes. > # > # equate_on :a, :b > # > # _is equivalent to_ > # > # def ==(o) > # self.a == o.a && self.b == o.b > # end > # > # def eql?(o) > # self.a.eql?(o.a) && self.b.eql?(o.b) > # end > # > # def hash() > # self.a.hash ^ self.b.hash > # end > > def equate_on(*fields) > code = "" > code << "def ==(o) " << fields.map {|f| "self.#{f} == > o.#{f}" }.join(" && ") << " end\n" > code << "def eql?(o) " << fields.map {|f| "self.#{f}.eql? > (o.#{f})" }.join(" && ") << " end\n" > code << "def hash() " << fields.map {|f| > "self.#{f}.hash" }.join(" ^ ") << " end\n" > class_eval( code ) > fields > end I opt for the second solution because the anonymous module does not have any reuse effects - unless you cache it based on field names. :-) Kind regards robert -- use.inject do |as, often| as.you_can - without end