From: Trans Date: 2008-03-19T06:30:38+09:00 Subject: Re: Parametric module or injecting code via class method? On Mar 18, 12:59 pm, "Sean O'Halpin" wrote: > On Mon, Mar 17, 2008 at 9:14 AM, Robert Klemme > > wrote: > > On 17.03.2008 00:12, Sean O'Halpin wrote: > > > On Sun, Mar 16, 2008 at 9:30 PM, Robert Klemme > > > wrote: > > >> Yeah, but you can achieve the functionality without modules at all - at > > >> the small cost of defining a single instance method in class Module. > > > > I suspect that Trans is looking for a general principle to follow and > > > is using equality as an example (but I'm open to be corrected of > > > course :) > > > Maybe. IIRC he did not state this. > > Indeed. Perhaps Trans can enlighten us as to the real application? > (Are you listening Tom?) There is the specific application which applies to equate_on, compare_on (aliased also as sort_on) and possibly initialize_on. However, seeing that's already three cases, a general principle does come into consideration. > True enough. As I said, I'm only surmising what Trans is after. I'm > not criticising your response to the concrete example (after all, > it is both pragmatic and to the point). Rather, I'm taking the > question Trans posed as an opportunity to discuss what I consider best > practice in the more general case. In the above cases, with the exception of initialize_on (I may just dump that one), I went with the capitlaize method approach, but used a little bit of Ara's concept. Eg. module Equatable def self.identify(base, *accessors) base.send(:define_method, :identity){ accessors } self end def ==(o) identity.all?{ |a| send(a) == o.send(a) } end def eql?(o) identity.all?{ |a| send(a).eql?(o.send(a)) } end def hash identity.inject(0){ |memo, a| memo ^ send(a).hash } end end class Module def Equatable(*fields) Equatable.identify(self, *accessors) end end I did something similar with Comparable, albeit a little different b/c Comparable already exists in the standard library. I figure this is a good way to go b/c the method doesn't really take up any new name space because the module already exists. > > Yeah, but happens only if you include modules. My point here was that > > the same behavior can be achieved by a single method in class Module. > > And in this particular case (defining equivalence) it is so general that > > it should even be part of the std lib. > > Agreed. (Lots of other things I'd like to see there too, and some I'd > rather see not there - but that's a different story :) I'd like to dig into these questions a bit more as well --except for the fact that I am sick of them. To be straight forward about it, Ruby itself is torn. It makes method extensions a snap, which we all know has proven itself as a distinct advantage of Ruby. But in turn it's inheritance system does nothing to make it easy to do it in a robust way. In short, I've come to the (long and drawn out) conclusion that Ruby's mixin system is crap. T.