我有一个循环,根据文件中包含的文件名分配不同的变量名。
每个变量都设置为空数组。
filenames = ['file1', 'file2']
filenames.each do |filename|
"@data_" + "#{filename}" = [] # used @ as I need these variables externaly from the loop
end
这给了我以下错误
syntax error, unexpected '=', expecting keyword_end
我不明白的是,如果我使用
filenames.each do |filename|
p "@data_" + "#{filename}"
end
它正确呈现
@data_file1
@data_file2
如果我通过循环设置一个空数组
filenames.each do |filename|
@data = []
end
p @data
#=> []
它也有效......
感谢您的帮助!
答案 0 :(得分:4)
我建议使用数据结构,而不是使用元编程合成实例变量 1 。
为什么不呢:
@data = filenames.inject({}) { |h, v| h[v] = []; h }
# => { "file1" => [], "file2" => [] }
现在您可以在{file1'数组对象中引用@data['file1']
。
1。但是为了记录,这是一种方式:
class A
def f x, y
self.class.send :attr_accessor, x
send "#{x}=", y
end
end
a = A.new
a.f 'new_instance_variable', 12345
p a.new_instance_variable
答案 1 :(得分:2)
最简单的解决方案,如果你确定你的文件名数组的清理,那就是:
filenames = ['file1', 'file2']
filenames.each do |filename|
eval "@data_#{filename} = []"
end
答案 2 :(得分:2)
您在"@data_" + "#{filename}" = []
中所做的是将空数组实例([]
)分配给String实例("@data_file1"
),因此syntax error, unexpected '=', expecting keyword_end
您应该做的是将[]
分配给实例变量:@data_file
,而不是字符串:"@data_file"
。
您可以使用instance_variable_set
类的Object
方法实现此目的:
filenames = ['file1', 'file2']
filenames.each do |filename|
instance_variable_set("@data_#{filename}".to_sym, [])
end
答案 3 :(得分:1)
为什么在同一个字符串中使用字符串连接和插值...
类似
p "@data_#{filename}"
与您的
相同p "@data_" + "#{filename}"
现在这不起作用,因为你试图说出string =你需要评估字符串的其他东西
eval("@data_#{filename} = []")