2015-02-23 6 views
0

Я надеюсь прокрутить каталог json-файлов и преобразовать их в рубиновые хэши. Моя функция петлевого файла захватывает каждый файл успешно, и файлы находятся в правильном формате json. Вот мой код:Отсутствует неявное преобразование файла в строку

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 

Любая идея о том, что происходит или что мне нужно сделать, чтобы привести в порядок мои файлы, так что они могут быть разобраны правильно?

ответ

4

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, потому что имя метода заканчивается ?.

+0

Спасибо! Изначально после строки dir.exists?(), Которую я делал, почему-то я изменил это. Я понимаю ваше мышление, и это действительно повторяемо и ненужно. Документация json, как вы заявили, довольно ужасна. Спасибо за объяснение, я ноб для рельсов, и это очень помогает мне. – James

Смежные вопросы