变量魔术和从文件

问题描述:

读假设,我得到以下文件(input.txt中):变量魔术和从文件

name = "Peter" 
age = 26 
family_status = married 

提到线可以存储在一个随机的顺序,谎言:

family_status = married 
name = "Peter" 
age = 26 

在我的程序中,我也有变量family_status,年龄名称。我如何在单个循环中读取文件中的这些行并为这些值分配相应的变量?

设置变量

这取决于几个事实。

  • 什么样的变量,你有(局部变量,实例变量,类变量,或全局变量)
  • 什么样的类型是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找到。

你可以试试这个。不漂亮但上一行:

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

假设该文件是真的定期为你的榜样,您可以啜一切都变成一个很好的哈希是这样的:

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

这就给了你:

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

但后来你真的需要一些特定于变量的代码来执行所需的任何类型处理,特别是对于任何family_status是...