-1

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"
end

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?

Thanks!

Cheers, Kyle

EDIT for clarity:

Ok, my understanding of send was incorrect.

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

So the loop above would create three arrays: a_data,b_data,c_data

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

So a_data[0] => "foo"

Thanks!

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
              end
            end
          end

Thanks for y'all's help guys!

KD100
  • 123
  • 1
  • 4
  • 2
    What do you mean by `object with a name`? Using `send` you can send messages to objects, not create them. Also, objects do not have a name, then can have an attribute called `name` if you define it which you don't seem to do. Please give more details on what you're trying to achieve. – Nic Nilov Jun 29 '16 at 10:57
  • 2
    why do you wanna do this? if I understand you correctly, you want to be able to [dynamically set local variables](http://stackoverflow.com/questions/4963678/dynamically-set-local-variables-in-ruby), but as the post suggested, using a hash should be good – lusketeer Jun 29 '16 at 11:03
  • in my actual code, I have an array of hashes. Each hash has a name and a list of keywords. I want to loop through the array of hashes, match the hash's keywords to strings in a larger text, then save the sentences of those matches to a new array with the hash's name. – KD100 Jun 29 '16 at 11:06
  • what do you need the variables for? it makes no sense to dynamically set variables, since you are limited to hardcoding the rest. The hash seems to fit all your needs – davegson Jun 29 '16 at 11:08
  • Based off your last comment, why not create a new hash with the keyword matches? – davegson Jun 29 '16 at 11:10
  • What's wrong with `map`-ping the original array, getting an array in result? – Vasfed Jun 29 '16 at 11:11
  • Created a hash with the matches and works brilliantly! Thanks for y'alls help – KD100 Jun 29 '16 at 12:05

1 Answers1

0

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"
end

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 Hash.new([]). Then you won't need data[key] ||= [] at all, because Hash.new([]) 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"
end

p @a_data # ["foo"]

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

pavel.nosov87
  • 116
  • 1
  • 7