1

I create an empty hash chickens, and key-value pairs are then added over time.

chickens = {} 
chickens.merge!("Davison"=>"plucky")
chickens.merge!("Mortimer"=>"sullen")
chickens.merge!("Chauncey"=>"forlorn") 

for name,mood in chickens do puts "#{name}: #{mood}" end

produces

Mortimer: sullen
Chauncey: forlorn
Davison: plucky

but I don't desire this. How do I cycle through the chickens in the order they were added?

sawa
  • 165,429
  • 45
  • 277
  • 381
user2493615
  • 317
  • 1
  • 8

2 Answers2

2

The short answer is: update your Ruby. Ruby 1.9 is years old and works the way you want (as does current Ruby, 2.0). If you insist on ancient, unsupported Ruby, there's an OrderedHash class available via a gem:

gem install orderedhash

Your code would then become:

require 'rubygems'
require 'orderedhash'

chickens = OrderedHash.new
# The rest stays the same

Again, I recommend instead just upgrading your Ruby installation.

P.S. Your code would be much more Ruby-like if you iterate over the Hash like this:

chickens.each do |name, mood|
  puts "#{name}: #{mood}"
end
Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • I didn't know my Ruby was old! I'm using CodeAcademy Labs, which I assumed would be current. Do you know of another site like that, that has the current Ruby? Also, you don't have to be so mean. Obviously (from the question I asked) I'm very new to this, and obviously I want to be using the current, supported version! – user2493615 Jun 22 '13 at 05:59
  • 7
    I don't see any meanness here. Just straight-up matter-of-fact. – Grant Birchmeier Jun 22 '13 at 06:03
  • Thing is, why would anyone, especially a total noob who would ask a question like I asked, "insist on using ancient, unsupported Ruby"? He knew I was using it by mistake, and didn't know any better. How couldn't he have? – user2493615 Jun 22 '13 at 06:06
  • @user2493615 I'm not too familiar with Rubies-in-the-browser, but http://tryruby.org is at least closer to modern -- it's 1.9.2 and supports ordered Hashes. – Darshan Rivka Whittle Jun 22 '13 at 06:06
  • Oh, how about this one? Does this look appropriate? http://www.compileonline.com/execute_ruby_online.php – user2493615 Jun 22 '13 at 06:08
  • 2
    @user2493615 I'm very sorry if something in my tone sounded mean to you. I assure you that no meanness was intended. The fact of the matter is that 1.8.7 is considered unsupported and isn't good for using or learning with. – Darshan Rivka Whittle Jun 22 '13 at 06:08
  • Well thank you for telling me that! I had no idea. Codeacademy should update their site! – user2493615 Jun 22 '13 at 06:09
  • @user2493615 It looks like that one is also on 1.8.7. – Darshan Rivka Whittle Jun 22 '13 at 06:09
  • Doesn't it say up top, Ruby 2.0.0p0? – user2493615 Jun 22 '13 at 06:10
  • @user2493615 It does, but it's apparently incorrect. `puts VERSION` shows 1.8.7, and a quick test shows 1.8-era unordered Hashes. – Darshan Rivka Whittle Jun 22 '13 at 06:12
  • Ok, what is the simplest way to get Ruby on my system? – user2493615 Jun 22 '13 at 06:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/32199/discussion-between-darshan-computing-and-user2493615) – Darshan Rivka Whittle Jun 22 '13 at 06:14
  • 1
    @user2493615 "why would anyone, especially a total noob who would ask a question like I asked, "insist on using ancient, unsupported Ruby"? He knew I was using it by mistake, and didn't know any better. How couldn't he have? " You misread and make assumptions about Darshan's comment. There was nothing wrong with what he said. Often we see people who can't/won't update, so he was addressing the "can't" update aspect I believe. He has repeatedly been very friendly and accurate in his answers so I think he was being consistent here. To summarize, he said "try OrderedHash". – the Tin Man Jun 23 '13 at 05:37
  • @user2493615, regarding authoritative information about Ruby's state, look to http://www.ruby-lang.org. You shouldn't blindly trust other sites, even Stack Overflow because web pages get stale. Also, http://www.ruby-lang.org has links to the current Ruby installs. I'd recommend looking at [RVM](http://rvm.io/rvm/install) or [rbenv](https://github.com/sstephenson/rbenv) to install Ruby in a sandbox. – the Tin Man Jun 23 '13 at 05:46
0

@DarshanComputing began talking about making the code more Ruby-like, but here's how I would do the sample code in its entirety:

chickens = {} 
chickens["Davison"] = "plucky"
chickens["Mortimer"] = "sullen"
chickens["Chauncey"] = "forlorn"

chickens.each do |name, mood| 
  puts "#{name}: #{mood}"
end

Using merge is fine, but it's also verbose. You'll see a lot of Ruby programmers take the more simple path and add the key/value pair directly, rather than rely on a mutating method.

Using for to loop over something is definitely not Ruby-like. Though the language supports it, its use is eschewed by Ruby developers consistently. The reason is, for name, mood ... adds name and mood to the local variables, unlike each which confines them inside the do block. Littering the variable space with temporary variables is bad-form. For instance, after running the original code I can do:

[7] (pry) main: 0> name
"Chauncey"
[8] (pry) main: 0> mood
"forlorn"
the Tin Man
  • 158,662
  • 42
  • 215
  • 303