From: Ross Bamford Date: 2006-04-14T17:40:09+09:00 Subject: Re: Rubyesque way to do multiple <=> On Fri, 2006-04-14 at 16:49 +0900, Victor Shepelev wrote: > > >def <=> (other) > > > res = ComplexCustomComparator.compare(sex, other.sex) > > > return res if res != 0 > > > > > > #if they have the same sex, do other comparisons > > >end > > > > > >Foooooo! > > > > > >How can I do the former in more elegant way? > > > > > > > > How about something like (untested): def <=>(other) [:name, :age, :sex].map do |attr,comp| ComplexCustomComparator.compare(send(attr), other.send(attr)) end.find { |e| e.nonzero? } || 0 end Or if you have to use a different comparator for each attribute: def somewhere_else_eg_initialize @comparators = [NameComparator.new, AgeComparator.new, SexComparator.new] end def <=>(other) [:name, :age, :sex].zip(@comparators).map do |attr,comp| comp.compare(send(attr), other.send(attr)) end.find { |e| e.nonzero? } || 0 end Probably not the most efficient way (two iterations) but it should work I think. -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk