I have a loop which should assign different variable names depending on filesname which are contained in an array.
Each variable is set as an empty array.
filenames = ['file1', 'file2']
filenames.each do |filename|
"@data_" + "#{filename}" = [] # used @ as I need these variables externaly from the loop
end
This gives me the following error
syntax error, unexpected '=', expecting keyword_end
What I don't understand is if I use
filenames.each do |filename|
p "@data_" + "#{filename}"
end
it renders correctly
@data_file1
@data_file2
And if I set an empty array through the loop
filenames.each do |filename|
@data = []
end
p @data
#=> []
it work开发者_运维问答s too...
Thanks for your help!
I would recommend using a data structure rather than synthesizing instance variables1 with meta-programming.
Why not just:
@data = filenames.inject({}) { |h, v| h[v] = []; h }
# => { "file1" => [], "file2" => [] }
Now you can just reference @data['file1']
where you want the 'file1' Array object.
1. But for the record, here is one way:
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
Simplest solution, if you're sure about the sanitsed-ness of your filenames array, would be:
filenames = ['file1', 'file2']
filenames.each do |filename|
eval "@data_#{filename} = []"
end
What you're doing in "@data_" + "#{filename}" = []
is assigning empty Array instance ([]
) to a String instance ("@data_file1"
), hence syntax error, unexpected '=', expecting keyword_end
You should want to do is to assign []
to instance variable: @data_file
, not string: "@data_file"
.
You can achieve that with instance_variable_set
method of class Object
:
filenames = ['file1', 'file2']
filenames.each do |filename|
instance_variable_set("@data_#{filename}".to_sym, [])
end
Why are you using string concatenation and interpolation in the same string...
something like
p "@data_#{filename}"
is the same as your
p "@data_" + "#{filename}"
Now this won't work because you are trying to say string = something else you need to evaluate the string
eval("@data_#{filename} = []")
精彩评论