3

I have a class whose initialize method defines a few instance variables and does some calculations. I need to create about 60 objects of that class. Each object has an ID number at the end. E.g.:

object1 = Dynamic.new(x, y)
object2 = Dynamic.new(x, y)
object3 = Dynamic.new(x, y)
...

I could just define them all by hand, but that would be quite inefficient. Is there any way to dynamically create each object?

sawa
  • 165,429
  • 45
  • 277
  • 381
  • You could just push them into an array. Have you tried that? Like: **objs = Array.new** and then for each new instance you'd do **objs.push(Dynamic.new(x,y))**. – Ed de Almeida May 13 '16 at 00:13
  • 1
    This would make each instance associated with an index in the array, which is quite equivalent to having an ID in the variable name. – Ed de Almeida May 13 '16 at 00:20
  • 1
    Not clear what you mean by "Each object has an ID number at the end". – sawa May 13 '16 at 00:44
  • 3
    It is not useful to create that many variables like that. It is likely an XY-question. – sawa May 13 '16 at 00:44
  • You can't create local variables dynamically: http://stackoverflow.com/questions/18552891/how-to-dynamically-create-a-local-variable – TeWu May 13 '16 at 00:54
  • Dynamically creating named variables like that is not well supported in any language I can think of. Most of the time you'd just create items in an Array or Hash, as in `object[1]`(Array or Hash with numeric key) or `data[:object1]` (Hash with named key). Is there a reason this is not workable for you case? – Andrew Schwartz May 13 '16 at 01:18
  • 1
    Could you explain (in a comment would be fine) how you will be using those instances? That information is not needed to answer the question, but it would satisfy the curiosity of several readers. It might also prompt suggestions for alternative approaches. – Cary Swoveland May 13 '16 at 01:50
  • Your question is unclear. What do you mean by "is there any way to dynamically create each object?" Objects are *always* created dynamically in Ruby, there is no other way. – Jörg W Mittag May 13 '16 at 07:53

3 Answers3

3

You can always make a loop and push all the objects into an array. An array position might also be needed for knowing which object is each. This isn't quite what you wanted (atleast I don't think so), but it should suffice.

class Dynamic
@@instances_of_class = 0
  def initialize(x,y)
  #...
  @array_position = @@instances_of_class
  @@instances_of_class += 1
  end
end

ary = []
50.times do 
ary << Dynamic.new(x,y)
end

Edit: This solution, as said in the comments, can cause bugs if you change the array, so here's an alternate solution.

require 'File.rb'
i = 1
varFile = File.open("File.rb","a+")
50.times do
varFile.puts "variable#{i} = Object.new"
i += 1
end

Inside of File.rb will be 50 uniquely named variables that you can use.

TheLuigi
  • 46
  • 1
  • 4
  • This solution is very brittle. You can create `ary` just fine, but what next? Say, you remove first element from `ary` - uh-oh, all the `@array_position`s are wrong. You can't modify `ary` in anyway without introducing potential bug. So why is this answer accepted? @Jonthemanman – TeWu Jun 01 '16 at 11:13
  • @TeWu - I added another solution that (I think) is better than my first one. Enjoy. :) – TheLuigi Jun 06 '16 at 00:25
1

I would be curious to know why you need this. It's an unusual requirement, and often that means that you can avoid the problem instead of solving it. I think TheLuigi's solution would work, but if you use a class variable then these Id's will be shared across multiple classes. You can instead use an instance variable, with something like the following:

class A
  def self.next_id
    @id ||= 0 ; @id += 1
  end

  def initialize
    @id = A.next_id
  end
end

A.new
# => #<A:0x007fd6d414c640 @id=1>
A.new
# => #<A:0x007fd6d41454a8 @id=2>
Ramfjord
  • 872
  • 8
  • 14
-1

If you just want sixty objects accessible from a variable, you should have them in an array referred to by a single variable.

objects = Array.new(60){Dynamic.new(x, y)}

Your object1, object2, ... will correspond to objects[0], objects[1], ... respectively.

sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    This is by far the best answer. So why is it downvoted instead of being accepted? Is there something wrong with this answer, and I'm not seeing it? – TeWu Jun 01 '16 at 11:21