I am hoping to loop through a directory of json files and convert them into ruby hashes. My file looper function grabs every file successfully, and the files are in correct json format. Here is my code:
def self.update_server
if Dir.exist?("log/order_errors") == true
logger.debug "#{Dir.entries("log/order_errors")}"
Dir.foreach("log/order_errors") { |f|
logger.debug "Retrieved #{f}"
File.open(f, "r") { |current_file|
JSON.parse(current_file)
}
}
else
logger.error "Was unable to find the directory specified."
end
end
Any idea of what is going on or what I need to do to tidy up my files so that they can be parsed correctly?
JSON.parse()
takes a string as an argument--not a file:
require 'json'
File.open('data.json') do |f|
JSON.parse(f)
end
--output:--
...no implicit conversion of File into String (TypeError)...
This is the way to do it:
require 'json'
File.open('data.json') do |f|
hash = JSON.parse(f.read) #***HERE***
p hash
end
--output:--
{"x"=>1, "y"=>2}
The json module's docs are horrible, which unfortunately is typical of ruby. The docs say that the argument to parse() is a JSON document
, which certainly sounds more like a File than a String. What the docs should say is that the argument needs to be a String in json format.
By the way, in this line:
if Dir.exist?("log/order_errors") == true
...the exist?() method call is replaced by its return value, so if the directory exists ruby will convert that line to:
if true == true
Then ruby has to do the comparison true == true
, and ruby replaces the comparison with the result of the comparison, i.e. true
to produce this:
if true
Now, what if you wrote this instead:
if Dir.exist?("log/order_errors")
Once again, the exist?() method call is replaced by its return value, and if the directory exists, you will get this:
if true
If the directory doesn't exist, the exist?() method call is replaced by false
, producing this:
if false
Therefore, writing == true
after the exist?() method call is both a waste of time to type, and it wastes processing time because it requires ruby to do an extra comparison. You'll get the same result without doing the comparison, as shown above. The rule is: if a method returns true or false, you don't need to write == true
after it. And in ruby it is usually pretty easy to tell when a method returns true or false because the method name will end with a ?
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With