Different behaviour in irb and ruby

I’m new to Ruby and just finished my first program.

simple quiz program

questions={“Question 1”=>“Answer 1”,
“Question 2”=>“Answer 2”,
“Question 3”=>“Answer 3”,
“Question 4”=>“Answer 4”,
“Question 5”=>“Answer 5”,
“Question 6”=>“Answer 6”,
“Question 7”=>“Answer 7”,
“Question 8”=>“Answer 8”,
“Question 9”=>“Answer 9”,
“Question 10”=>“Answer 10”}
score=0
i=0
while i<10
puts questions.keys[i]
if gets.chomp == questions.values[i]
puts “Good answer !”
score+=1
else
puts “Bad answer !”
end
i+=1
end

puts “Your score is #{score}/10.”

When I past it in irb(0.9.5) it just runs fine, but when it runs with
ruby(1.8.7) or (1.9.2) the order of the questions changes.

Can someone explain me what goes wrong (and why)?

Thank you.

On Mon, Jan 3, 2011 at 7:38 PM, Vincent V. [email protected]
wrote:

 "Question 8"=>"Answer 8",

puts “Bad answer !”
end
i+=1
end

puts “Your score is #{score}/10.”

When I past it in irb(0.9.5) it just runs fine, but when it runs with
ruby(1.8.7) or (1.9.2) the order of the questions changes.

Can someone explain me what goes wrong (and why)?

If you want to access the answers by question number, you should use
an array and not a Hash. In Ruby 1.9 the Hash maintains the keys in
insertion order, but this is not the case in Ruby 1.8, I think. I’m
not sure why you find that behaviour in 1.9.2. In any case, I think
you should use an Array.

Jesus.

com/ http://www.ruby-forum.com/.

Relying on hash is something I shy from, it is not implemented across
all
Rubies. Like Jesus said, the point of a hash is to be able to access the
elements by their keys, rather than indexes. So, given that you know the
question, in your example you would put it into the hash, and the hash
would
give you back the answer. That isn’t how you are using it, and so things
are
weird.

To use it as a hash, just iterate over it:

simple quiz program

problems={
“Question 1”=>“Answer 1”,
“Question 2”=>“Answer 2”,
}

score=0

problems.each do |question,answer|
puts question
if gets.chomp == answer
puts “Good answer !”
score+=1
else
puts “Bad answer !”
end
end

puts “Your score is #{score}/#{problems.size}.”


But I think that is still misleading, since you aren’t using it as
key/value
pairs. Really, you are using it as an array of arrays, so this is
probably
more straighforward:

problems= [
[“Question 1”,“Answer 1”],
[“Question 2”,“Answer 2”],
]


Here is an example showing how you could use hashes with this. Though
this
script is simple enough in its current form, that I don’t think it is
really
necessary.

problems = [
{ :question => “Question 1” , :answer => “Answer 1” },
{ :question => “Question 2” , :answer => “Answer 2” },
]
score=0
problems.each do |problem|
puts problem[:question]
if gets.chomp == problem[:answer]


If your data ever gets complicated enough that the above is better than
the
array of arrays, then you probably want to start thinking about turning
it
into a class. If its just a collection of data, I like to use a struct,
then
if it gets complicated enough to need methods, I would later turn it
into a
class. Structs are great for carefree prototyping like this.

Problem = Struct.new :question , :answer

problems = [
Problem.new(“Question 1”,“Answer 1”),
Problem.new(“Question 2”,“Answer 2”),
]
score=0
problems.each do |problem|
puts problem.question
if gets.chomp == problem.answer