From: "David A. Black" Date: 2005-10-24T11:27:35+09:00 Subject: Re: [SORT?] by x,y allowing x,y to be passed as parms Hi -- On Mon, 24 Oct 2005, New 2 Ruby wrote: > Question: Are there better ways to do this > sort within the container class? I see class variables and eval, so I will go out on a limb and say: yes :-) > Have class CD with several fields defined, > @list_of_CDs array in class CD_List holding CD pointers, > and a couple of methods to sort array of pointers by any two fields. > > Below is relevant class entries and code. > > class CD > attr_reader :size, :cusip, :issuer, :matures, ... > .... > class CD_List > @@sortkey1= @@sortkey2 = "" > def initialize @list_of_CDs = Array.new end > ... > def new_ord(key1='size',key2='matures') #Provide defaults > @@sortkey1, @@sortkey2 = key1, key2 # Set class variables > @list_of_CDs.sort! { |a,b| cmp_item(a,b) } # Sort in place > end > def cmp_item (a,b) # Adapted from Ryan Pavlik > # Allow different sort fields via Class variables > f1 = eval('a.'+@@sortkey1) <=> eval('b.'+@@sortkey1) > f2 = eval('a.'+@@sortkey2) <=> eval('b.'+@@sortkey2) > (f1 == 0 ? f2 : f1) > end One possibility would be to have CD objects themselves know how to compare themselves with each other via a <=> method, though then you'd have to have them know how to change that which might be slow and cumbersome. If you want to keep the sorting intelligence in the CD_List object, I would do it more simply. You don't actually need class variables anywhere you've used them. Possibly instance variables... but possibly not anything, unless you really need to save the sort keys beyond the sort operation for some reason. Here's a little mini-version that doesn't do much but might give you some ideas. (You could also have CD_List inherit from Array, though inheriting from base classes is often fraught with unexpected problems.) class CD attr_reader :size, :cusip def initialize(size,cusip) @size,@cusip = size,cusip end end class CD_List def initialize @cds = [] end def add(cd) @cds << cd end def new_ord(key1='size',key2='cusip') @cds.replace(@cds.sort_by {|cd| [cd.send(key1), cd.send(key2)] }) end end c = CD.new(10,"abc") d = CD.new(5,"def") e = CD.new(5,"bcd") cdl = CD_List.new cdl.add(c) cdl.add(d) cdl.add(e) p cdl.new_ord David -- David A. Black dblack@wobblini.net