在初始化期间定义Struct

时间:2014-07-17 09:30:36

标签: ruby

我有一个类,它读取动态CSV文件,并希望根据CSV的标题创建一个结构。

伪代码就是这样:

class SomeClass
  def initialize(csvfile)
    @csv = CSV.open(csvfile, options.....)
    .....
    headers = @csv.headers  # => [:line, :error, :user, ........]   <==this is dynamic
    RECORD = Struct.new(headers)
    load_data
  end

  def load_data
    @records = []
    @csv.each do |r|
      @records << RECORD.new(r.fields)
    end
  end
end

问题是常量不能(不应该)动态定义。那么,解决这个问题的正确方法应该是什么呢?

2 个答案:

答案 0 :(得分:2)

你不必使用常数。使用实例变量。

class SomeClass
  def initialize(csvfile)
    @csv = CSV.open(csvfile, options...)
    ...
    headers = @csv.headers
    @record = Struct.new(headers)
    load_data
  end
  def load_data
    @records = []
    @csv.each do |r|
      @records << @record.new(r.fields)
    end
  end
end

答案 1 :(得分:0)

@sawa's回答是正确的。我会在这里添加更多内容。

常量用于存储不会更改的值。如果在程序中更改常量,则可能是 bug 。 Ruby正试图提供帮助并说“坚持下去!我认为这里发生了一些奇怪的事情。你说你希望这是一个常数,但现在它正在改变!”

在Ruby中,由于我刚才所说的原因,你永远不会允许在方法定义中放置常量赋值。如果您尝试在方法中执行常量赋值,则会出现语法错误。根据您的需要,您可以在方法中使用任何变量,但不能使用常量变量。

如果你这样做

Y = 1
#then
Y = 2
# warning: already initialized constant Y
# warning: previous definition of Y was here

但如果你试试,

def meth arg
  C = arg
end
# then 
# SyntaxError: dynamic constant assignment
# C = arg
#   ^