46

I can go one way using

require 'json'

def saveUserLib(user_lib)
    File.open("/Users/name/Documents/user_lib.json","w") do |f|
    f.write($user_lib.to_json)
    end
end

uname = gets.chomp
$user_lib["_uname"] = uname
saveUserLib($user_lib)

but how do i get it back again as my user_lib?

beoliver
  • 5,579
  • 5
  • 36
  • 72
  • 3
    Small code criticism: you should not hardcode the file path into your method. You should either have your method accept a file path, or put a constant at the top of your file with the path to use. Rule of thumb (there are always exceptions): if you ever hard code a number (other than perhaps 1) or user-facing string inside a method, you're making your code more fragile and harder to maintain. – Phrogz Jan 29 '12 at 17:57
  • when I remove my `$`'s I get the following error: `
    ': undefined local variable or method `user_lib' for main:Object (NameError)
    – beoliver Jan 29 '12 at 18:07
  • 1
    but about the path - this i am aware - but it was for a quick test! thanks for the heads up though – beoliver Jan 29 '12 at 18:10

3 Answers3

97

You want JSON.parse or JSON.load:

def load_user_lib( filename )
  JSON.parse( IO.read(filename) )
end

The key here is to use IO.read as a simple way to load the JSON string from disk, so that it can be parsed. Or, if you have UTF-8 data in your file:

  my_object = JSON.parse( IO.read(filename, encoding:'utf-8') )

I've linked to the JSON documentation above, so you should go read that for more details. But in summary:

  • json = my_object.to_json — method on the specific object to create a JSON string.
  • json = JSON.generate(my_object) — create JSON string from object.
  • JSON.dump(my_object, someIO) — create a JSON string and write to a file.
  • my_object = JSON.parse(json) — create a Ruby object from a JSON string.
  • my_object = JSON.load(someIO) — create a Ruby object from a file.

Alternatively:

def load_user_lib( filename )
  File.open( filename, "r" ) do |f|
    JSON.load( f )
  end
end

Note: I have used a "snake_case" name for the method corresponding to your "camelCase" saveUserLib as this is the Ruby convention.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • what is the difference between `JSON.dump` / `.to_json` / `JSON.generate` and then `JSON.parse` / `JSON.load` ? – beoliver Jan 29 '12 at 17:35
  • @user969617 I've edited my answer to show the difference, and summarize the ways of dealing with JSON data. – Phrogz Jan 29 '12 at 17:48
  • Both `JSON.parse` and `JSON.load` can "create a Ruby object from a JSON string" – pje Aug 30 '12 at 13:17
  • 1
    As this is the top answer, I think you should correct the JSON.parse call to `JSON.parse(IO.read(filename))` – mwallisch Mar 10 '13 at 20:57
  • @walfish3d But of course, and thanks. (You're also welcome in the future to edit someone else's answer when such an obvious mistake has been made. ;) – Phrogz Mar 11 '13 at 02:40
  • 3
    Contrary to what you may expect, you get stuff like `user['name']` not `user[:name]` – ashes999 Apr 16 '14 at 01:15
2

here is some example:

require 'json'

source_hash = {s: 12, f: 43}
json_string = JSON.generate source_hash
back_to_hash = JSON.parse json_string
alexkv
  • 5,144
  • 2
  • 21
  • 18
2

JSON.load will do the trick. Here's an example that goes both ways:

>> require 'json'
=> true
>> a = {"1" => "2"}
=> {"1"=>"2"}
>> b = JSON.dump(a)
=> "{\"1\":\"2\"}"
>> c = JSON.load(b)
=> {"1"=>"2"}
Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
Chris Bunch
  • 87,773
  • 37
  • 126
  • 127