Re: Parametric module or injecting code via class method?
2008/3/13, Trans <transfire@gmail.com>:
> 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
|