140

I am creating a hash in Ruby and want to write it to a JSON file, in the correct format.

Here is my code:

tempHash = {
    "key_a" => "val_a",
    "key_b" => "val_b"
}
fJson = File.open("public/temp.json","w")
fJson.write(tempHash)
fJson.close

And here is the contents of the resulting file:

key_aval_akey_bval_b

I'm using Sinatra (don't know what version) and Ruby v 1.8.7.

How can I write this to the file in the correct JSON format?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
dt1000
  • 3,684
  • 6
  • 43
  • 65
  • What you're doing is actually something I use a lot to document the JSON and YAML structures I use. I'll write a small piece of code to save the YAML/JSON to a file, then build same structures showing what the data should look like before and/or after dumping and reloading. So, though your code isn't working quite right, stick with this process as it makes life easier in the long run. – the Tin Man Mar 31 '11 at 23:30
  • Have a look at this SO answer: http://stackoverflow.com/questions/1684588/how-to-do-ruby-object-serialization-using-json – Charlie Martin Mar 31 '11 at 23:18

4 Answers4

208

Require the JSON library, and use to_json.

require 'json'

d = {
  "a": 1,
  "b": 2,
}

File.open('out.json', 'w') do |f|
  f.write(d.to_json)
end

Your temp.json file now looks like:

{"a": 1, "b": 2}
duhaime
  • 25,611
  • 17
  • 169
  • 224
Mike Lewis
  • 63,433
  • 20
  • 141
  • 111
  • 3
    Minor improvement: I suggest the block form: `File.open(...){ |f| f << h.to_json }` – Phrogz Mar 31 '11 at 23:41
  • 26
    `JSON.pretty_generate(tempHash)` is also rad http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-pretty_generate – Connor Leech Mar 01 '14 at 14:42
  • Is there any version now which does not generate the memory overhead of building the string in memory first? This is a larger memory fragmentation problem if the json is getting into the megabytes range. 10 years later somebody should have optimized it – Lothar Mar 17 '23 at 08:49
109

With formatting

require 'json'
tempHash = {
    "key_a" => "val_a",
    "key_b" => "val_b"
}
File.open("public/temp.json","w") do |f|
  f.write(JSON.pretty_generate(tempHash))
end

Output

{
    "key_a":"val_a",
    "key_b":"val_b"
}
Anders B
  • 3,343
  • 1
  • 26
  • 17
  • 1
    I like the "a+" option. Doesn't clobber existing data. – boulder_ruby Jul 20 '12 at 23:17
  • 2
    @boulder_ruby appending may only make sense if the file format is JSONlines (one JSON object per line) and that hardly ever combines well with `pretty_generate`, unless the consumer of the output is a human. Even then, it's better to generate JSONlines and use something like `jq` to see the output. – Sim Jun 16 '18 at 19:41
22

This question is for ruby 1.8 but it still comes on top when googling.

in ruby >= 1.9 you can use

File.write("public/temp.json",tempHash.to_json)

other than what mentioned in other answers, in ruby 1.8 you can also use one liner form

File.open("public/temp.json","w"){ |f| f.write tempHash.to_json }
Haseeb A
  • 5,356
  • 1
  • 30
  • 34
3

To make this work on Ubuntu Linux:

  1. I installed the Ubuntu package ruby-json:

    apt-get install ruby-json
    
  2. I wrote the script in ${HOME}/rubybin/jsonDEMO

  3. $HOME/.bashrc included:

    ${HOME}/rubybin:${PATH}
    

(On this occasion I also typed the above on the bash command line.)

Then it worked when I entered on the command line:

jsonDemo
Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
daggett
  • 31
  • 2