Shwunky Shwunky - 7 months ago 29
Ruby Question

How to Initialize Class Arrays in Ruby

I want to create an empty array as a class instance variable in Ruby. However, my current method does not seem to work.

Here is my code:

class Something
@something = []
def dosomething
s = 5
@something << s
end
end


When I call the function, it gives me an undefined method traceback.
However, if I do something similar with class variables, i.e.:

class Something
@@something = []
def dosomething
s = 5
@@something << s
end
end


This works perfectly.

I know I can use the initialize method to actually create an empty list for @something, but is there another way of doing this without using the initialize method? And why does this work for class variables?

EDIT: Fixed typo

Answer

At first you have a typo. Change Classto class. Next I suggest to use the initialize method. While creating a new object this is the perfect place to initialize instance variables.

class Something
  @@my_class_variable = [1]

  def initialize
    @something = []
  end

  def dosomething
    s = 5
    @something << s
  end

  def self.get_my_class_variable
    @@my_class_variable
  end
end

Your script will be read and executed from top to bottom and after this, you can access the class Something. While the parser reads your script/class/module you can define class variables (@@), execute mixins and extend the class with other modules. This is why you can define a class variable, but you can not define an instance variable. Because actually you have no instance object from your class. You only have a class object. In ruby everything is an object. And your class object has a defined class variable now:

Something.get_my_class_variable
# => [1]

Now you can create an instance from your class. With Something.new the initialize method will be invoked and your instance variable will be defined.

something = Something.new
something.dosomething
# => [5]

Later, if you are familar with this you can define getter and setter methods with attr_reader, attr_writer and attr_accessor for instance objects or cattr_reader, cattr_writer and cattr_accessor for class objects. For example:

class Something
  attr_reader :my_something

  def initialize
    @my_something = []
  end

  def dosomething
    s = 5
    @my_something << s
  end
end

something = Something.new
something.my_something
# => []
something.dosomething
# => [5]
something.my_something
# => [5]