0

我开始研究 Ruby,并认为我会构建一些东西;我开始在其中编写一个简单的配置文件解析器。简单的原则是你给它一个格式正确的文件,它会吐出一个设置的哈希值。例如,这是一个配置文件:

localhost: 4000;
auto: true;

这就是它所回馈的:

{"localhost" => "4000", "auto" => "true"}

现在,当使用以下代码直接输入它时,我已经让它工作了:

  def spit_direct(input = "", *args)
    spat = Hash.new
    args.each do |arg|
      if input.include? arg
        strip = input.match(/#{arg}:\s(\w*);/)
        spat[arg] = strip[1]
      else
        # error message
        break
      end
    end
    spat
  end

  spit_direct("localhost: 4000; auto: true;", "localhost", "auto")
  # => {"localhost"=>"4000", "auto"=>"true"}

这可以按我的意愿工作,但是如果可以提供实际文件会更好。我想出了以下代码,但它似乎只返回第一个设置,而不是第二个设置:

  def spit_file(input = "", *args)
    spat = Hash.new
    args.each do |arg|
      File.open(input).each_line do |line|
        if line.include? arg
          strip = line.match(/#{arg}:\s(\w*);/)
          spat[arg] = strip[1]
        else
          # error message
          break
        end
      end
    end
    spat
  end

如果我向它提供一个文件,该文件config.cnfg的内容与上述几个设置文件的内容相同,如下所示:

spit_file("(path)/config.cnfg", "localhost", "auto")

它只返回:

# => {"localhost"=>"4000"}

这是为什么?我昨晚花了几个小时,但似乎无法弄清楚问题所在。

4

2 回答 2

2

你这样做是错的。对于 args 中的每个 arg,再次打开文件,如果该文件的第一行与 arg 匹配,则更新哈希,然后关闭文件,否则立即关闭文件。

反转循环嵌套:

def spit_file(input = "", *args)
  spat = Hash.new
  File.open(input).each_line do |line|
    args.each do |arg|
      if line.include? arg
        strip = line.match(/#{arg}:\s(\w*);/)
        spat[arg] = strip[1]
      end
    end
  end
  spat
end


1.9.3p327 :001 > spit_file('cfg.cfg', 'localhost', 'auto')
 => {"localhost"=>"4000", "auto"=>"true"}
于 2013-03-29T13:13:00.500 回答
0

如果没有该 break 语句,您的代码将正常工作。它打破了 args.each 循环而不是 each_line 循环。当一行第一次没有您所在的确切参数时,循环中断。您应该改用 next 语句。

def spit_file(input = "", *args)
    spat = Hash.new
    args.each do |arg|
      File.open(input).each_line do |line|
        if line.include? arg
          strip = line.match(/#{arg}:\s(\w*);/)
          spat[arg] = strip[1]
        else
          # error message
          next
        end
      end
    end
    spat
  end
于 2013-03-29T13:33:33.083 回答