Kyle D Kyle D - 3 months ago 5x
Ruby Question

Ruby: How to access object created by send without name?

What I'm trying to do in Ruby is to create an object with a name that comes from a string (in an array for instance). Then I want to use that object in further code.

So, for example:

array = ["a", "b", "c"]
array.each do |x|
send x + '_data'
x + '_data' = []
x + '_data' << "foo"

The above, of course, does not work.

I've racked my brain, the docs, and SO all morning on this. Your help is appreciated!

Any ideas?



EDIT for clarity:

Ok, my understanding of
was incorrect.

For each string in the array, I want to create an array.

So the loop above would create three arrays:

Then, I want to populate each array with "foo".

a_data[0] => "foo"


Double edit:

Here's my slightly altered actual code with fuller explanation of what I'm doing:

I have a big json file of thousands of tweets (not just the text, but the full json from twitter api).

I then have an array of hashes based with topics and associated keywords -- e.g. "cooking" -> "utensils", "oven", "microwave".

I want to loop through the array of topic hashes and see if any of the topic keywords match words in the tweet text.

If there's a match, I want to add that tweet to a new array.

# topics is an array of hashes. Each hash contains title and list of keywords
topics.each do |topic|
# create an array with the topic's name to store matches
(topic[:title] + '_tweets') = []
topic[:keywords].each do |kw|
# loop through array of hashes (parsed json) to check for keyword matches in strings
tweets.each do |tweet|
text = tweet["text"]
# if string contains keyword, add to the topic's array
if text.include? kw
(topic[:title] + '_tweets') << tweet

Thanks for y'all's help guys!


Why not create a Hash to keep the data you need?

array = ["a", "b", "c"]
data = {}
array.each do |x|
  key = x + '_data'
  data[key] ||= []
  data[key] << "foo"

Also, note data[key] ||= [] trick. It means "look into data[key]. If it is nil, initialize it with empty array". It is idiomatic way to initialize something once.

You can declare data as[]). Then you won't need data[key] ||= [] at all, because[]) will create a hash that returns an empty array if the value associated with the given key has not been set.

This is much more flexible than using variable variables from PHP

But if you REALLY need something like this, you can do the following:

array = ["a", "b", "c"]
array.each do |x|
  instance_variable_set '@' + x + '_data', []
  instance_variable_get('@' + x + '_data') << "foo"

p @a_data # ["foo"]

Here we create an instance variable in the context of current object instance. Its name MUST begin with @.