130

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
  • 155,156
  • 41
  • 207
  • 295
dt1000
  • 3,514
  • 6
  • 42
  • 64
  • 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

196

Require the JSON library, and use to_json.

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

Your temp.json file now looks like:

{"key_a":"val_a","key_b":"val_b"}
Mike Lewis
  • 61,841
  • 20
  • 140
  • 111
  • 3
    Minor improvement: I suggest the block form: `File.open(...){ |f| f << h.to_json }` – Phrogz Mar 31 '11 at 23:41
  • 23
    `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
  • Why do you have to require the json library here? How does that require statement change the code? – duhaime Nov 17 '21 at 16:45
105

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,107
  • 1
  • 24
  • 16
  • 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
18

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
  • 4,002
  • 1
  • 32
  • 30
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,038
  • 11
  • 115
  • 133
daggett
  • 31
  • 2