Variables in OOP

Posted by Aniqa Elahi on November 16, 2016

In Object Oriented Programming we get to see a lot of variables ..For example Instance Variable, Class Variable, and Local Variables.

** Instance Variable**

Lets discuss them in detail, consider a class named Teachers

class Teachers

attr_accessor :name

def initialize(name)
 name
end

def print_name
puts name
end

end
 

now we create an object of this class with our first teacher name

Muhammad = Teachers.new(“Muhammad”) # an Instance of class Teachers is being created with a name “ Muhammad”

Muhammad.print_name

what do you expect from th eabove code will it assign name provided by us when creating object of class “Teachers”?

we will get the following error message

NameError: undefined local variable or method name’ for #`

It looks like name variable in initialize method has a local scope and is known to initialize method only … How can we make it accessible to other functions of the class ? For this reason Ruby provide us a very simple method and that is using @ symbol before a variable name and it will make it accessible to all the methods in a class, such variable is known as “Instance Variable” we can write the above program as follows

class Teachers

attr_accessor :name

def initialize(name)
 @name = name
end

def print_name
puts @name
end

end

now we create an instance of class Teachers

Hanna = Teachers.new(“Hanna”) # an Instance of class Teachers is being created with a name “ Hanna Khan”

Hanna.print_name

=> Hanna Khan #output

our instance variable provided us ability to access name which we supplied at the time of object creation

class Variable

In the above example we used an instance variable and call function print_name on that instance. Can we keep track of all the teachers being created using some instance variable for example @names ? The answer is yes through arrays for example we write the above program as follows

class Teachers

attr_accessor :name, :names

@names = [] 

def initialize(name)
     @name = name		 
		 @names << name
end

def print_name
     puts @name
end

def print_names
     @names.each{|teacher_name| puts teacher_name}
end

end

Now we create three teacher instances

aniqa = Teachers.new("Aniqa")
saad = Teachers.new("Saad")
umar = Teachers.new("Umar")

and call function print_names

aniqa.print_names

our expected result should be

Aniqa
Saad
Umar

But we get an undefined method error .. why is that? The answer is that we defined names[] as an instance variable so all it can do is to work with an instance and being unaware of other instances being created. So any push method (« ) wont work on it .

How can we fix this problem? And the answer is very easy just add another @ symbol before @names (i.e @@names) and it will make it a class array and we will be able to push information of each new instance to it such variable is known as a Class Variable. We can write the above program as follows

what will be the Output?

class Teachers

attr_accessor :name, :names

@@names = [] 

def initialize(name)
     @name = name		 
		 @@names << name
end

def print_name
     puts @name
end

def print_names
     @@names.each{|teacher_name| puts teacher_name}
end

end

Now we create three teacher instances

aniqa = Teachers.new("Aniqa")
saad = Teachers.new("Saad")
umar = Teachers.new("Umar")

and call function print_names

aniqa.print_names

An we get our desired result as follows

Aniqa
Saad
Umar

Local Variable

It is simple variable which we can use in a class method and it stays there and has a local scope in th emethod for example in the above example in the print_names method of Class Teachers

def print_names
     @@names.each{|teacher_name| puts teacher_name}
end

teacher_name is a local variable and has a local scope in the each method.