I’m going through this tutorial: http://tutorials.jumpstartlab.com/projects/jsattend.html
In iteration 7, step 3 we get to sort a hash, called state_data, which has nil as a key. The proposed solution is:
state_data = state_data.sort_by{|state, counter| state unless state.nil?}
Unfortunately, this isn’t working on ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.0.0]. For example:
~% irb
>> things = { nil => "a", 2 => "b", 3 => "c" }
>> things.sort_by { |k, v| k unless k.nil? }
ArgumentError: comparison of NilClass with 2 failed
from (irb):6:in `sort_by'
from (irb):6
from /Users/jacopo/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
The same goes with the equivalent:
>> things.sort_by { |k, v| k if k }
ArgumentError: comparison of NilClass with 2 failed
from (irb):3:in `sort_by'
from (irb):3
from /Users/jacopo/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
In the tutorial’s case, since it’s sorting on the state two letter code, a possible solution is:
state_data = state_data.sort_by{|state, counter| state.nil? ? "ZZ" : state }
which is clearly a hack.
What’s the Ruby-way to deal with this?
The line
is effectively equivalent to a simple
state_data.sort, because(state unless state.nil?) == statein any case. What you could do is to seperate the proper keys from thenilkeys and only sort the former:In the more general case, you can also define a custom comparison function like this:
By quickly looking at this, you see that it’s pretty ugly. In fact, you should rather rethink your choice of data structure here.
nilkeys don’t seem very sensible to me.UPDATE: From looking at the tutorial you linked to, I take it that there is a lot of suboptimal information in there. Take a look at the following piece of “Ruby”, for example:
You could write this much more cleanly and get the same result:
The author also recommends code like
While the Ruby idiom would be:
This shows that the author doesn’t seem to be very apt in Ruby. Thus, I can’t recommend that tutorial.