I am working through the Ruby Koans(A tutorial project of Ruby). In the About_Dice_Project, it's demanded to create a class named DiceSet. I succeed, but there is a interesting question.
Here's the code :
class DiceSet
# Attribute reader
attr_reader :values
# Initializer
def initialize
@values = []
end
# Roll method
def roll(dice_amount)
@values = Array.new(dice_amount) { rand(1..6) }
end
end
And this test is interesting :
def test_dice_values_should_change_between_rolls
dice = DiceSet.new
dice.roll(5)
first_time = dice.values
dice.roll(5)
second_time = dice.values
assert_not_equal first_time, second_time,
"Two rolls should not be equal"
end
THINK ABOUT IT:
If the rolls are random, then it is possible (although not likely) that two consecutive rolls are equal. What would be a better way to test this?
My idea is to test the object_id of first_time
and second_time
, using
assert_not_equal first_time.object_id, second_time.object_id
. It works but am i right ? As a beginner in Ruby and programming, what is an object_id
indeed ?
By the way, is it possible to justify the text in markdown ?
Any help will be appreciated !
You shouldn't compare object_id
s, but value
s.
a = [1, 2, 3]
b = [1, 2, 3]
puts a == b
#=> true
puts a.object_id == b.object_id
#=> false
By comparing object_id
s, you're testing if variables refer to the exact same object. In your case, first_time
and second_time
are created independently from each others, so they cannot reference the same object. They can have the same values, though.
One way to ensure that no two consecutive rolls are equal would be to use a while
loop :
class DiceSet
# Attribute reader
attr_reader :values
# Initializer
def initialize
@values = []
@last_values = []
end
# Roll method
def roll(dice_amount)
while @values == @last_values
@values = Array.new(dice_amount) { rand(1..6) }
end
@last_values = @values
@values
end
end
dice = DiceSet.new
dice.roll(5)
first_time = dice.values
dice.roll(5)
second_time = dice.values # <-- cannot be equal to first_time