开发者

Assign different variable names (which are nil array) through a loop

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} = []")
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜