2009-10-16 53 views
2

讀假設,我得到以下文件(input.txt中):變量魔術和從文件

name = "Peter" 
age = 26 
family_status = married 

提到線可以存儲在一個隨機的順序,謊言:

family_status = married 
name = "Peter" 
age = 26 

在我的程序中,我也有變量family_status,年齡名稱。我如何在單個循環中讀取文件中的這些行併爲這些值分配相應的變量?

回答

4

設置變量

這取決於幾個事實。

  • 什麼樣的變量,你有(局部變量,實例變量,類變量,或全局變量)
  • 什麼樣的類型是family_status(String,Symbol,等等)

我承擔你使用的實例變量爲:

def read_vars(io, vars) 
    io.each do |line| 
    # ensure the line has the right format (name = var) 
    raise "wrong format" unless line=~ /^\s*(\w+)\s*=\s*"?(.*?)"?\s+$/ 
    var= :"@#{$1}" 
    # pick the type of the data 
    value= case vars[var] 
    when String 
     $2 
    when Integer 
     $2.to_i 
    when Symbol 
     $2.to_sym 
    else 
     raise "invalid var" 
    end 
    instance_variable_set(var, value) 
    end 
end 

read_vars(File.read("input.txt", :@age => Integer, :@name => String, :@family_status => Symbol) 

如果你不使用實例變量,你必須更改instacne_variable_setvar= :"@...行可以滿足您的需求。該代碼具有以下優點:

    哪些變量可以設置
  • 你控制哪些類型的這些變量具有
  • 您可以輕鬆地添加新的變量和/或改變類型的變量不改變讀取
  • 你控制代碼
  • 您可以使用此代碼來讀取完全不同的文件,而無需編寫新的代碼爲它

閱讀作爲YAML

如果您的需求不像您的問題那麼具體,我會採用完全不同的方法來解決這個問題。

我會將input.txt寫成yaml文件。在YAML語法它是這樣的:

--- 
name: Peter 
age: 26 
family_status: :married 

你可以閱讀:

YAML.load(File.read("input.txt")) # => {"name" => "Peter", "age" => 26, "family_status" => :married } 

要當心,如果你不控制input.txt文件,你不控制哪些類型的數據將有。我將這個文件命名爲input.yaml而不是input.txt。如果你想知道更多,關於如何編寫yaml文件請看:http://yaml.kwiki.org/?YamlInFiveMinutes。關於yaml和紅寶石的更多信息可以在http://www.ruby-doc.org/stdlib/libdoc/yaml/rdoc/index.html找到。

0

你可以試試這個。不漂亮但上一行:

class Test 
    attr_accessor :name, :age, :family_status 

    def load 
    File.foreach('input.txt') do |line| 
     match = line.match /^(\S+)\s*=\s*"?(\S+?)"?\s*$/ 
     self.send("#{match[1]}=", match[2]) if match 
    end 
    end 
end 

test = Test.new 
test.load 
+0

從外部來源評估輸入不可取。在你的情況下,你的輸入可能會調用意外的方法。 你甚至不用你的代碼來確定變量。你正在調用方法。這隻適用於公共可寫屬性,這可能並不總是它想要的。 我假設提問者不希望所有變量都是字符串。用你的代碼,你只能創建字符串。 – johannes 2009-10-16 12:22:22

2

假設該文件是真的定期爲你的榜樣,您可以啜一切都變成一個很好的哈希是這樣的:

input = IO.read("input.txt") 
input_hash = Hash[*input.gsub(/"/,"").split(/\s*[\n=]\s*/)] 

這就給了你:

=> {"name"=>"Peter", "family_status"=>"married", "age"=>"26"} 

但後來你真的需要一些特定於變量的代碼來執行所需的任何類型處理,特別是對於任何family_status是...