Home > Mobile >  How do I keep track of automatically instanced unassigned objects in basic Ruby?
How do I keep track of automatically instanced unassigned objects in basic Ruby?

Time:12-20

I am trying to build a mastermind game, and I am hoping to have my code instance its own objects containing information about the place and color of the step in the passcode. This is so I can vary the length of the passcode without hard coding it. Is there a way to keep track of these objects, seeing as I am not personally assigning a variable? Can my program assign the instances their own variable names, and if so how would I do that?

#Builder for password objects
class ColorPicks
  attr_reader :color, :place
  def initialize(color, place)
    @color = color
    @place = place
  end
end

# Determines how long the password should be
module StartUp
  def self.how_many
    @how_many
  end
  def HowManyColors 
    p "How long should the computer's code be?"
    @how_many = gets.chomp.to_i
  end 
end

#Instances the password objects from ColorPicks
class Printer
  include StartUp
  @@i = StartUp.how_many
  @@place = 1
  COLORS = {1 => 'red', 2 => 'blue', 3 => 'green'}

  def self.code_maker
    for a in 1..@@i do 

      number_of_colors = COLORS.length
      random_number = rand(number_of_colors)
      ColorPicks.new(COLORS[random_number], @@place)
      @@place  = 1
    end
  end
end

PS. Sorry, I am new to programming.

CodePudding user response:

References to objects are stored in variables, like the instance variable @color in your ColorPicks class. Only the instance itself can access the instance variable directly. Other objects can only access it indirectly via method calls, e.g. attr_reader :color creates a color method that returns the object, @color is referring to.

If you want to store a variable number of objects, you typically use a collection like Array, Hash or Set. Instead of assigning every single object to a separate variable, you add the objects to the collection and just assign the collection to a variable, e.g.

class CodeGenerator
  COLORS = %w[red green blue]

  attr_reader :code

  def initialize(size)
    @code = Array.new(size) { COLORS.sample }
  end
end

Example usage:

generator = CodeGenerator.new(5)
generator.code
#=> ["blue", "green", "red", "blue", "red"]

The object returned by generator.code is the array we assigned to @code in initialize. To access individual objects in the collection, you can use Array#[]: (note that arrays are zero based in Ruby)

generator.code[0] #=> "blue"
generator.code[1] #=> "green"

In the above example, I'm using plain strings to keep the code simple. The concept however applies to all objects, i.e. you could just as well add instances of ColorPicks instead of strings. You also don't have to use the Array.new constructor to build an array. It's perfectly fine to start with an empty array and to add your items in a loop one after another, e.g.:

def initialize(size)
  @code = []
  (1..size).each do |i|
    @code << ColorPicks.new(COLORS.sample, i)
  end
end

CodePudding user response:

You could write some variant the following, where all instances created are saved to an array held by a class instance variable.

class ColorPicks
  @instances = []
  class << self
    attr_reader :instances
  end

  attr_reader :color, :place
  def initialize(color, place)
    self.class.instances << self
    @color = color
    @place = place
  end
end

Note that @instances is a class instance variable and its getter is created in ColorPick's singleton class.


Create an instance.

stefan = ColorPicks.new("blue", "Bremen")
  #=> <ColorPicks:0x00007fba7bb29958 @color="blue", @place="Bremen">

Then,

stefan.color
  #=> "blue"
stefan.place
  #=> "Bremen"

We can now see the instances of ColorPicks that have been created:

ColorPicks.instances
  #=> [#<ColorPicks:0x00007fba7bb29958 @color="blue", @place="Bremen">]

Now create a second instance. ​ cary = ColorPicks.new("blue", "Victoria") #=> #<ColorPicks:0x00007fba7babc7e0 @color="blue", @place="Victoria">

Then,

cary.color
  #=> "violet"
cary.place
  #=> "Victoria"

Now,

ColorPicks.instances
  #=> [#<ColorPicks:0x00007fba7bb29958 @color="blue", @place="Bremen">,
  #=>  #<ColorPicks:0x00007fba7babc7e0 @color="Violet", @place="Victoria">]
  • Related