Ruby Hash not working API - Colon

I am trying to request an api via 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 should state ":" instead of "=>" like this

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


when i use them i get this error:

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


I was wondering why it was? Rubies don't look like hashes with ":"? The reason I am asking is because on foo_3 I have a json file that I would like to add, which is formatted like this:

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


So when I try to use it, you also get:

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


There are about 2000 id's - so I can't change everything: to => manually and that will be dynamic too. So I'm a little stuck!

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



source to share

3 answers

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, the characters 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 worry changing your hashes to the new syntax. It works fine.


I'm just re-reading your question and I notice that you mention a "JSON file" that you want to insert into the ruby ​​hash. I don't know what code you are using for this, but it is not going to fly. The JSON specification requires quoted key names, and the Ruby syntax syntaxes (both of them) are not JSON-compliant. So you can't just take some JSON and pretend it's a ruby ​​hash. You can take it apart.

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 the hash syntax that is IS json compatible. This way you can take a json string and just evaluate it.

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


Don't rate it. If it's a JSON string, use JSON.parse

on it.



I think this is from the Ruby version 1.9

(not sure), but the syntax should be like this anyway:

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




I think you are all right. the method to_json

will take care of the formatting for you.

>> require 'json'
=> true
>> 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
=> {"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}]}




All Articles