16

I am not a ruby expert and this is giving me trouble. But how Would I go about creating an array of objects/classes in ruby? How would initialize it/declare it? Thanks in advance for the help.

This is my class, and I want to create an array of it:

class DVD
  attr_accessor :title, :category, :runTime, :year, :price

  def initialize()
    @title = title
    @category = category
    @runTime = runTime
    @year = year
    @price = price
  end
end
3
  • since it's within a class and I want other methods within the class to access it, I tried: @@movies = Array DVD.new but quickly found out that didn't work. Commented Jan 26, 2013 at 1:24
  • You mean you want to create an array with the class instances? Commented Jan 26, 2013 at 1:27
  • Check if this is of any help: stackoverflow.com/questions/6365638/… Commented Jan 26, 2013 at 1:31

3 Answers 3

20

Ruby is duck typed (dynamic typing) And almost everything is an object, so you can just add any object to an array. For example:

[DVD.new, DVD.new]

will create an array with 2 DVDs in it.

a = []
a << DVD.new

will add the DVD to the array. Check the Ruby API for the full list of array functions.

Btw, if you want to keep a list of all the DVD instances in the DVD class you can do this with a class variable, and add it to that array when you create a new DVD object.

class DVD
  @@array = Array.new
  attr_accessor :title, :category, :runTime, :year, :price 

  def self.all_instances
    @@array
  end

  def initialize()
    @title = title
    @category = category
    @runTime = runTime
    @year = year
    @price = price
    @@array << self
  end
end

now if you do

DVD.new

you can get the list of all the DVDs you have created so far:

DVD.all_instances
Sign up to request clarification or add additional context in comments.

3 Comments

Not almost everything is an object, everything is an object. Also, in general, class instance variables should be preferred over class variables.
Except really blocks are objects: def f &block; block; end; f {}. Which returns, well, an object.
@AndrewMarshall yes, like that they are converted to a proc, but when you have to yield for it, it is not an object :) therefore not everything, but almost everything is an object.
10

two_DVD = Array.new(2){DVD.new}

1 Comment

The first time I tried this: Array.new(2, DVD.new) and this ended up creating 2 copies of the same object. Then I found your answer "Array.new(2){DVD.new}" and found it to create 2 unique objects, which is what I needed. Thank you!
7

In order to create an array of objects in Ruby:

  1. Create the array and bind it to a name:

    array = []
    
  2. Add your objects to it:

    array << DVD.new << DVD.new
    

You can add any object to an array, at any time.

If you wish to have access to every instance of the DVD class, then you can rely on ObjectSpace:

class << DVD
  def all
    ObjectSpace.each_object(self).entries
  end
end

dvds = DVD.all

By the way, the instance variables are not being initialized correctly.

The following method call:

attr_accessor :title, :category, :run_time, :year, :price

Automatically creates attribute/attribute= instance methods to get and set the value of the instance variables.

The initialize method, as defined:

def initialize
  @title = title
  @category = category
  @run_time = run_time
  @year = year
  @price = price
end

Sets the instance variables, despite taking no arguments. What effectively happens is:

  1. The attribute reader method is called
  2. It reads the unset variable
  3. It returns nil
  4. nil becomes the value of the variable

What you want to do is pass the values of the variables to the initialize method:

def initialize(title, category, run_time, year, price)
  # local variables shadow the reader methods

  @title = title
  @category = category
  @run_time = run_time
  @year = year
  @price = price
end

DVD.new 'Title', :action, 90, 2006, 19.99

Also, if the only required attribute is the DVD's title then you can do it this way:

def initialize(title, attributes = {})
  @title = title

  @category = attributes[:category]
  @run_time = attributes[:run_time]
  @year = attributes[:year]
  @price = attributes[:price]
end

DVD.new 'Second'
DVD.new 'Third', price: 29.99, year: 2011

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.