2013-03-29 2 views
0

Я начал изучать Руби и думал, что я что-то создаю; Я начал писать простой синтаксический анализатор конфигурации. Простым принципом является то, что вы кормите его правильно отформатированным файлом и выплевываете хэш настроек. Например, это конфигурационный файл:Почему это только возвращает первую настройку?

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

Почему? Я потратил пару часов на это прошлой ночью, но не могу понять, в чем проблема.

ответ

3

Вы делаете это неправильно. Для каждого arg в args вы снова открываете файл, и если первая строка этого файла совпадает с аргументом 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"} 
+0

Проклятье, спасибо большое. Я тоже не был уверен в порядке петель. – raf

+0

@dnnx Вы можете присоединиться к сайту? http://chat.stackoverflow.com/rooms/27184/ruby-conceptual –

1

Ваш код будет работать без этого заявления перерыва. Он вырывается из цикла args.each, а не цикла each_line. В первый раз, когда в строке нет точного аргумента, в котором вы находитесь, цикл прерывается. Вместо этого вы должны использовать следующий оператор.

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 
Смежные вопросы