Hi Robert,
On 19/01/12 19:52, Robert K. wrote:
frequently
Descending, secondary.
repeat until you are done with the most important key
I guess you can generalize this using an array of Lambdas.
One potential disadvantage of this for your particular case is that,
a.magic(b) is always performed even if a.key0 != b.key0. As you have
stated, this is quite expensive, and can make the above general scheme
much more expensive than your way.
This is totally inefficient because it goes through the original data
set (which might be large) multiple times. The complexity of #magic
only adds to this.
Very true.
Cool- thanks for that. I won’t be able to use it directly as the last key
sort for most of the things I am doing is typically expensive, but I’m still
quite interested in different possible approaches. Thankyou. 
Please don’t, there are much better approaches (see botp’s for
example). Here are more
Yes, it’s not directly suitable for what I’m doing but the different
approach was interesting- there are cases where I might be able to have
the input come in already sorted against one of the keys without cost.
It got me thinking, anyway.
foo.sort! {|a,b|
Ascending, primary.
(a.key0<=> b.key0).nonzer0? ||
Descending, secondary.
(b.key1<=> a.key1).nonzero? ||
A tricky and expensive comparison, tertiary.
a.magic(b)
}
Very, very neat; and nice find on “nonzero?”.
My first thought was
that “nonzero?” surely returns a boolean and this would break it- but it
looks like “nonzero?” with numeric return was designed for this exact
problem. 
I was wondering if there was a nice way to drop the “rv” from my
solution- this looks like the best way.
foo.sort_by {|a|
[
Ascending, primary.
a.key0,
Descending, secondary, only if numeric.
-a.key1,
# A tricky and expensive comparison, tertiary.
a.create_magic_key
]
}
I’d stumbled on sort_by initially, I suspect I’ll use it when I can
precompute the comparisons easily (this is sometimes the case, sometimes
not).
All these approaches can also be stored in a lambda and used from there
YourClass::SORT_FOO = lambda {|a| [a.key0, -a.key1, a.create_magic_key]}
YourClass::SORT_BAR = lambda {|a,b| (a.key0<=> b.key0).nonzero? || … }
enum.sort_by&YourClass::SORT_FOO
enum.sort&YourClass::SORT_BAR
Excellent stuff. 
I’m not at all familiar with the “enum.sort_by&YourClass::SORT_FOO”
syntax at this point, so I might need to read up on that. I can at least
partly guess from the context though.
Thankyou for your very detailed input on this one, excellent stuff! 
Garth