没有隐式将文件转换为字符串

时间:2015-02-23 23:56:46

标签: ruby json

我希望循环遍历json文件的目录并将它们转换为ruby哈希。我的文件循环功能成功抓取每个文件,文件格式正确。这是我的代码:

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

知道发生了什么事情或我需要做些什么来整理我的文件以便正确解析它们?

1 个答案:

答案 0 :(得分:6)

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}

json模块的文档非常糟糕,不幸的是它是典型的ruby。文档说parse()的参数是JSON document,这听起来更像是文件而不是字符串。文档应该说的是参数需要是json格式的String。

顺便说一下,在这一行:

if Dir.exist?("log/order_errors") == true 

...存在的?()方法调用被其返回值替换,因此如果该目录存在,ruby会将该行转换为:

if true == true

然后ruby必须进行比较true == true,并且ruby将比较结果替换为比较结果,即true来产生这个:

if true

现在,如果你改为写这个:

if Dir.exist?("log/order_errors")

再次,存在的?()方法调用被其返回值替换,如果该目录存在,您将得到:

if true

如果目录不存在,则存在的?()方法调用被false替换,产生:

if false

因此,在存在的?()方法调用之后写== true既浪费时间键入又浪费处理时间,因为它需要ruby来进行额外的比较。如上所示,您无需进行比较即可获得相同的结果。规则是:如果方法返回true或false,则不需要在其后面写== true。在ruby中,通常很容易判断方法何时返回true或false,因为方法名称将以?结束。