Charlie Davies Charlie Davies - 1 month ago 7
Ruby Question

Ruby Hash not working API - Colon

I am trying to query an api through JSON / REST using Ruby.

require 'rubygems'
require 'rest-client'
require 'json'


###Request Build#####
url = 'http://site_name'
request ={
"format"=>'json',
"foo"=> {"first"=>1.1,"second"=>2.2},
"foo_1"=>300,
"foo_2"=>"speed",
"foo_3"=>[
{"id"=> "abc123", "first"=> 1.8, "second"=> 2.8},
{"id"=> "abc456", "first"=> -1.5, "second"=> 1.2}
]
}.to_json

### go go go ###
response = RestClient.post(url,request, :content_type => :json, :accept => :json)
puts response


The above works, it will query the api just fine. However the API documentation I am using says I should have ":" instead of "=>" like this

"format":'json',
"foo":{"first":1.1,"second":2.2},
"foo_1":300,
"foo_2":"speed",
"foo_3":[
{"id":"abc123", "first":1.8, "second":2.8},
{"id":"abc456", "first":-1.5, "second":1.2}
]
}


when I do use them I get this error:

new.rb:10: syntax error, unexpected ':', expecting tASSOC
"format":'json',


I was wondering why this was? Does ruby not like hashes with ":" ? The reason I ask is that on foo_3 I have a json file I would like to put in that is formatted like:

[{"id":"abc123","first":1.8, "second": 2.8},
{"id":"abc456","first":-1.5, "second": 1.2}]


So when I try and use it also get the:

new.rb:10: syntax error, unexpected ':', expecting tASSOC


There are around 2000 id's - so I cant change all : to => manually and this will be dynamic as well. So I am a little stuck!

SO either I have to find a way to change all ":" to "=>" before I send the array or, I am doing something stupid and very wrong.

Thanks

Answer

This is the new hash syntax from Ruby 1.9. These two forms are identical

{foo: 1, bar: 2}
{:foo => 1, :bar => 2}

After formatting to JSON, symbols become strings, so

{foo: 1, bar: 2}.to_json
{:foo => 1, :bar => 2}.to_json
{"foo" => 1, "bar" => 2}.to_json

all produce the same output.

Summary: don't bother changing your hashes to the new syntax. It's working just fine.

Update

I just re-read your question and noticed that you mention a "JSON file" that you want to insert into ruby hash. I don't know what code you use for this, but it's not gonna fly. JSON spec requires quoted key names, and Ruby hash syntaxes (both of them) are not JSON-compatible. So you can't just take some JSON and pretend that it's a Ruby hash. You can parse it, though.

require 'json'

json_string = "{\"id\":\"abc123\",\"first\":1.8, \"second\": 2.8}"
ruby_hash = JSON.parse json_string
# {"id"=>"abc123", "first"=>1.8, "second"=>2.8}

Update 2

Since ruby 2.2, there is a third variant of hash syntax which IS json compatible. So you can take a json string and simple eval it.

json_string = '{"id":"abc123","first":1.8, "second": 2.8}'
eval(json_string) # => {:id=>"abc123", :first=>1.8, :second=>2.8}

Don't eval it, though. If it's a JSON string, use JSON.parse on it.