13

I have this hash:

{
  "title"=>"Navy to place breath-test machines on all its ships", 
  "url"=>"http://feeds.washingtonpost.com/click.phdo?i=a67626ca64a9f1766b8ba425b9482d49"
} 

It turns out that

hash[:url] == nil

and

hash['url'] == "http://feeds.washingtonpost.com/click.phdo?i=a67626ca64a9f1766b8ba425b9482d49"

Why? Shouldn't it work with either?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Rick Button
  • 1,212
  • 13
  • 19

3 Answers3

23

Since a symbol is not the same as a string:

:url == 'url' #=> false

As hash keys they would be different. Perhaps you have seen this behavior in Rails? Ruby on Rails uses HashWithIndifferentAccess which maps everything to a String internally, so you can do this:

h = HashWithIndifferentAccess.new
h['url'] = 'http://www.google.com/'
h[:url] #=> 'http://www.google.com/'
Mark Thomas
  • 37,131
  • 11
  • 74
  • 101
  • 2
    It was Rails. Oh the life of learning Rails at the same time as Ruby. – Rick Button Mar 15 '12 at 01:45
  • 4
    Sorry to be pedantic, but HashWithInDifferentAccess actually just checks if the key is a Symbol and coerces in into a String if that's the case, not the other way around https://github.com/rails/rails/blob/3d6eafe32ed498784dba2b9782bbf7df47ebeb6b/activesupport/lib/active_support/hash_with_indifferent_access.rb#L152 – Lee Jarvis Mar 15 '12 at 01:48
4

:url is a Symbol which is different than the String 'url'

> :ruby == "ruby­"
=> false

You can convert back and forth between the two using to_s and to_sym

> "ruby".to_­sym
=> :ruby
> :ruby.to_s
=> "ruby"
Christopher Manning
  • 4,527
  • 2
  • 27
  • 36
2

Why?---Because :url and 'url' are different, i.e., :url != 'url'.

Shouldn't it work with either?---No.

sawa
  • 165,429
  • 45
  • 277
  • 381