我开始研究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"}
为什么会这样?昨晚我花了几个小时才看到它,但似乎无法弄清问题是什么。
答案 0 :(得分:3)
你做错了。对于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"}
答案 1 :(得分:1)
您的代码可以在没有该break语句的情况下运行。它打破了args.each循环而不是each_line循环。第一次一行没有你所在的精确arg时,循环就会中断。您应该使用下一个语句。
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