JSON.parse()
принимает строку в качестве аргумента - не файл:
require 'json'
File.open('data.json') do |f|
JSON.parse(f)
end
--output:--
...no implicit conversion of File into String (TypeError)...
Это способ сделать это:
require 'json'
File.open('data.json') do |f|
hash = JSON.parse(f.read) #***HERE***
p hash
end
--output:--
{"x"=>1, "y"=>2}
Docs В JSon модуля ужасны, который, к сожалению, типична рубина. Документы говорят, что аргумент parse() - это JSON document
, который, безусловно, звучит скорее как файл, чем строка. То, что должны сказать документы, состоит в том, что аргумент должен быть строковым в json-формате.
Кстати, в этой строке:
if Dir.exist?("log/order_errors") == true
... существует() вызов метода заменяется его возвращаемого значения, поэтому, если каталог существует рубин будет преобразовать эту строку в:
if true == true
Затем рубин должен сделать сравнение true == true
и рубин заменяет сравнение с результатом сравнения, т.е. true
производить это:
if true
Теперь, что если бы вы написали вместо этого:
if Dir.exist?("log/order_errors")
Еще раз, существуют() вызов метода заменяется возвращаемого значения, а если каталог существует, вы получите это:
?
if true
Если каталог не существует, то есть() вызов метода заменяется false
, производя это:
if false
Таким образом, запись == true
после вызова метода?() - это и пустая трата времени на вводе, и отнимает время обработки, потому что для рубинов требуется дополнительное сравнение. Вы получите тот же результат без сравнения, как показано выше. Правило: если метод возвращает true или false, вам не нужно писать == true
после него. И в рубине обычно довольно легко сказать, когда метод возвращает true или false, потому что имя метода заканчивается ?
.
Спасибо! Изначально после строки dir.exists?(), Которую я делал, почему-то я изменил это. Я понимаю ваше мышление, и это действительно повторяемо и ненужно. Документация json, как вы заявили, довольно ужасна. Спасибо за объяснение, я ноб для рельсов, и это очень помогает мне. – James