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!!!









