Charlie Davies Charlie Davies - 1 year ago 62
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 ={
"foo"=> {"first"=>1.1,"second"=>2.2},
{"id"=> "abc123", "first"=> 1.8, "second"=> 2.8},
{"id"=> "abc456", "first"=> -1.5, "second"=> 1.2}

### go go go ###
response =,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

{"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

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.


Answer Source

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.


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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download