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"}

これは私が望むように機能しますが、実際のファイルをフィードできる方がよいでしょう。次のコードを思いつきましたが、最初の設定のみを返し、2 番目の設定は返さないようです。

  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 の各引数に対して、ファイルを再度開きます。このファイルの最初の行が引数と一致する場合、ハッシュが更新され、ファイルが閉じられます。そうでない場合、ファイルはすぐに閉じられます。

ループのネストを反転します。

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 ステートメントがなくても機能します。each_line ループではなく、args.each ループから抜け出します。最初に行に正確な引数がない場合、ループは中断されます。代わりに 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 に答える