1

I have a related question here, but I'm posting another question to focus on a specific part of the problem.

Goal: Add script to my Ruby app which can read a local JSON file, parse it to a Ruby hash, and access the properties within it.

System: CentOS 7

File: Locally saved /tmp/valid.json file:

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [],
  "spouse": null
}

(That object borrowed from Wikipedia's article on JSON in an attempt to make sure that my problem isn't invalid JSON.)

Code:

require 'json'
data = File.read("/tmp/valid.json")
$evm.log(:info, data) #writes to log file, where I can see content of my JSON file
$evm.log(:info, "is data a hash ? ")
$evm.log(:info, data.is_a?(Hash).to_s) # prints false
$evm.log(:info, "is data a string? ")
$evm.log(:info, data.is_a?(String).to_s) # prints true
$evm.log(:info, "can I parse data?")
valid_ob = JSON.parse(data)
$evm.log(:info, "just parsed it, now print it")
$evm.log(:info, valid_ob)

That last line prints:

NoMethodError: undefined method `gsub' for #<Hash:0x0000000020951f
a8>

Why can't Ruby parse this string?

3
  • valid_obj is not a string. Maybe you want valid_obj.inspect. Commented Sep 5, 2020 at 5:16
  • 1
    "Why can Ruby not parse local JSON file?" – What makes you think it can't? The error occurs on the last line, which means Ruby has parsed the file just fine on line 9. The problem is clearly that you are passing something to $evm::log that it doesn't expect, but since you are not telling us what $evm::log is, there is nothing more we can say. Commented Sep 5, 2020 at 6:53
  • This appears to be an X/Y problem caused by a custom logger object receiving a hash, and does not appear to be a reproducible problem statement, or an issue with JSON data or parsing per se. Commented Sep 5, 2020 at 16:19

2 Answers 2

2

Have you tried printing the object normally, instead of using "$evm.log"? JSON.parse returns a hash, and it seems as though your logger is attempting to run a non-existent gsub method on it.

Sign up to request clarification or add additional context in comments.

3 Comments

Hello Robert Garrett, welcome! Thanks for your first attempt on posting an answer we do appreciate it! However, this post should be in comment section. Please have a look at this link, A good answer provides enough understanding of the question meanwhile illustrating the logic behind your solution, it not only solves the OP's issue, but also give the readers approaches on solving similar kind of problems. If it's a suggestion that doesn't contain any specific code, please post it as comment.
Unfortunately, I don't actually have enough reputation to just comment lol Even so, I'm effectively saying the same as the answer above, albeit far less elaborate.
@RobertGarrett THANK YOU. After days of misinterpreting the problem, your reply got me back on the right track. It was parsing correctly all along. I will def return to the ruby console for debugging in the future!
1

The problem is something in whatever you have assigned to $evm. The error message:

NoMethodError: undefined method `gsub' for #<Hash:>

indicates that when you call

$evm.log(:info, valid_ob)

the log method is attempting to call gsub on valid_ob. Most likely, log is meant to accept only strings and does no type checking on the object it receives.

If you need a simple, interactive way to run this Ruby code without using this $evm object, just run irb in your console and start typing in your Ruby code for parsing the JSON data:

require 'json'
 => true
data = File.read('/tmp/valid.json')
data.class
 => String
hash = JSON.parse(data)
hash.class
 => Hash
hash
 => {"firstName"=>"John", "lastName"=>"Smith", "isAlive"=>true, "age"=>27, "address"=>{"streetAddress"=>"21 2nd Street", "city"=>"New York", "state"=>"NY", "postalCode"=>"10021-3100"}, "phoneNumbers"=>[{"type"=>"home", "number"=>"212 555-1234"}, {"type"=>"office", "number"=>"646 555-4567"}], "children"=>[], "spouse"=>nil}

1 Comment

Thanks @anothermh! You were correct. I will def use the ruby console for debugging in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.