Bartłomiej Skwira
Bartłomiej Skwira

Reputation: 1848

Default hash values in Ruby (Rubykoans.com -> about_hashes.rb)

I'm going through about_hashes.rb from RubyKoans. 1 exercise got me puzzled:

 def test_default_value
    hash1 = Hash.new
    hash1[:one] = 1

    assert_equal 1, hash1[:one] #ok
    assert_equal nil, hash1[:two] #ok

    hash2 = Hash.new("dos")
    hash2[:one] = 1

    assert_equal 1, hash2[:one] #ok
    assert_equal "dos", hash2[:two] #hm?
  end

My guess is that Hash.new("dos") makes "dos" the default answer for all non-existent keys. Am I right?

Upvotes: 6

Views: 2329

Answers (2)

Pavling
Pavling

Reputation: 3963

The original of the koan is:

def test_default_value
  hash1 = Hash.new
  hash1[:one] = 1

  assert_equal __, hash1[:one]
  assert_equal __, hash1[:two]

  hash2 = Hash.new("dos")
  hash2[:one] = 1

  assert_equal __, hash2[:one]
  assert_equal __, hash2[:two]
end

The error is not in the koan, but in the assertion you've completed:

assert_equal nil, hash2[:two] #hm?

...should be

assert_equal "dos", hash2[:two] #hm?

Upvotes: 4

Aliaksei Kliuchnikau
Aliaksei Kliuchnikau

Reputation: 13719

Yes, you are right, looks like there is a mistake in ruby koans, hash2[:two] will return "dos"

Take a look at Hash.new method documentation

new → new_hash
new(obj) → new_hash
new {|hash, key| block } → new_hash

Returns a new, empty hash. If this hash is subsequently accessed by a key that doesn’t correspond to a hash entry, the value returned depends on the style of new used to create the hash. In the first form, the access returns nil. If obj is specified, this single object will be used for all default values. If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.

Sidenote: You can confirm your expectations in such cases by running the actual code or by executing couple of lines in irb or pry (I recommend pry).

Upvotes: 9

Related Questions