-1

I want to loop through an array of one word strings and turn them into instances of a class. Something like this:

names_array = ["jack", "james","jim"]

names_array.each { |name| name = Person.new }

I've tried using eval like (names_array.each { |name| eval(name) = Person.new }) but this doesn't seem to work. Is there anyway of doing this in Ruby?

EDIT Previous example was a little off on what I am really trying to do here is my exacted code.

students = ["Alex","Penelope" ,"Peter","Leighton","Jacob"]
students_hash = Hash.new {|hash, key| key = { :name => key, :scores => Array.new(5){|index| index = (1..100).to_a.sample} } }
students.map! {|student| students_hash[student]}

Where my problem is

students.each {|student_hash| eval(student_hash[:name].downcase) = Student.new(students_hash)}
sawa
  • 165,429
  • 45
  • 277
  • 381
Peter
  • 55
  • 3
  • 9
  • 2
    How do you plan to receive the students from the local variables again? Sounds like a [xy problem](http://meta.stackexchange.com/a/66378) to me. – spickermann Feb 09 '15 at 05:45
  • @spickermann: next thing he'll ask is how to get all local variables in an array/hash :) – Sergio Tulentsev Feb 09 '15 at 05:52
  • I second @spickermann: why do you want to do this? What are you hoping to achieve? – Sergio Tulentsev Feb 09 '15 at 05:55
  • 1
    I mean, if your input is dynamic (array), turning it into local variables is the worst data transformation known to mankind. I can't come up with another that is even less comfortable to work with. – Sergio Tulentsev Feb 09 '15 at 06:02
  • I'm not totally sure what you mean @spickermann? If you are referring to my last line and how I will access my new locally defined Student instances couldn't I just create a pre-defined array to shovel them into? Maybe pointing out my flawed logic would help better than a condescending comment – Peter Feb 09 '15 at 06:12

2 Answers2

1

I am not sure if I understand what you try to achieve. I assume you want to initialize some objects with values from an array. And store the instances in a way that allows quick access.

student_names = ['Alex', 'Penelope', 'Peter', 'Leighton', 'Jacob']

students = student_names.each_with_object({}) do |name, hash|
  student = Student.new(:name => name, :scores => Array.new(5) { rand(100) })
  hash[name.downcase] = student
end

When the students are store under their name in the students hash, you can receive them by their name:

students['alex'] #=> returns the Student instance with the name 'Alex'
spickermann
  • 100,941
  • 9
  • 101
  • 131
0

You can't. See How to dynamically create a local variable?

Ruby manipulates local variables using bindings, but here's the catch: a binding can only manipulate local variables that already existed when the binding was created and any variables created by the binding are visible only to the binding.

a = 1
bind = binding # is aware of local variable a, but not b
b = 3

# try to change the existing local variables
bind.local_variable_set(:a, 2)
bind.local_variable_set(:b, 2)
# try to create a new local variable
bind.local_variable_set(:c, 2)

a # 2, changed
b # 3, unchanged
c # NameError
bind.local_variable_get(:c) # 2

eval has the exact same behavior when you try to get/set a local variable since it uses a binding under the hood.

You should rethink your code along the lines that spickerman pointed out.

Community
  • 1
  • 1
Max
  • 21,123
  • 5
  • 49
  • 71