Class Instance Variables

Ruby has a unique concept, namely Class Instance Variables that is not common in other programming languages. Ruby has instance variables, class variables and class instance variables. Lets take a quick look at what I am talking about.

Example 1

class Resource
  @@developers = []


  def self.developers
    return @@developers
  end


  def add_to_pool
    @@developers << self
  end


  def initialize(resource_name)
    @resource_name = resource_name
  end
end


Resource.new(‘Matz’).add_to_pool
Resource.new(‘David’).add_to_pool
Resource.new(‘James’).add_to_pool


puts Resource.developers.size    # 3

The output is pretty obvious here. Now lets consider a practical problem with this approach.

Example 2

class RubyDeveloper < Resource; end
class JavaDeveloper < Resource; end


RubyDeveloper.new(‘Matz’).add_to_pool
RubyDeveloper.new(‘David’).add_to_pool


JavaDeveloper.new(‘James’).add_to_pool


puts RubyDeveloper.developers.size    # ?
puts JavaDeveloper.developers.size    # ?

The output here is:
>3
>3

Here’s the problem, how do we restrict the class variable to a given class and prevent any modification by its subclass?

Class Instance Variables to the rescue

Example 3

class Resource


  class << self
    def developers
      return @developers
    end


    def developers=(developers)
      @developers | |= [ ]
    end
  end


  def add_to_pool
    self.class. developers | |= [ ]
    self.class. developers << self
  end


  def initialize(resource_name)
    @resource_name = resource_name
  end
end


class RubyDeveloper < Resource; end
class JavaDeveloper < Resource; end


RubyDeveloper.new(‘Matz’).add_to_pool
RubyDeveloper.new(‘David’).add_to_pool


JavaDeveloper.new(‘James’).add_to_pool


puts RubyDeveloper.developers.size    # 2
puts JavaDeveloper.developers.size    # 1

Simplifying the code:

class << self
  def developers
    return @developers
  end


  def developers=(developers)
    @developers | |= [ ]
  end
end

can be achieved by:

class << self
  attr_accessor :developers
end

Rewriting the Resource class

class Resource
  class << self; attr_accessor :developers; end


  def add_to_pool
    self.class. developers | |= [ ]
    self.class. developers << self
  end


  def initialize(resource_name)
    @resource_name = resource_name
  end
end

Just to summarize:

Declaring the Class Instance Variable:

class << self; attr_accessor :developers; end

Accessing the Class Instance Variable:

Inside the class, where self is the class object:

self.developers

Inside an action in the class, where self is the instance:

self.class.developers

Hope that was interesting.
Happy coding!!!

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine

Advertisement

Leave a Comment

Filed under Ruby, Ruby on Rails

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s