Method Access Control in Ruby
Lets discuss the different types of access a method can have with an object.
Public Access
This means a method is available inside the class and outside of the class through an object. Public access is the default method access control in classes. Typically the keyword public
is not used unless a different access was listed before the public methods.
class Person
attr_accessor :name, :age def initialize(name)
@name = name
@age = 20
end def get_age
age
end
endbob = Person.new('Bob')
bob.name
=> 'Bob'
bob.get_age
=> '20'
Remember from our previous post the if a method is called without a receiver then the default receiver is the calling object, so age
in the method definition get_age is equal to self.age
= object.age
.
The method #name
is available outside of the class to the object bob
hence bob.name
returns 'Bob'
. The method #age
is available inside the class and is being called by another method #get_age
.
Private Access
This means a method is only available inside the class and not outside of the class. The private method can only be access from another method within the class. Private access is given to a method by using the keyword private
and defining the any method below it. All methods will be private unless another keyword is used to denote a new access level. ie public
or protected
.
class Person
attr_accessor :name
attr_writer :age def initialize(name)
@name = name
end def get_age
age
end
private
attr_reader :age
endbob = Person.new('Bob')
bob.age = 20
bob.age
=> NoMethodError (private method called...)
bob.get_age
=> 20
We can see that the getter method #age
is private and not be called outside of the class with the bob
object. The setter #age=()
is public which allow us to assign @age
to 20
to the bob
object. The only way to get access to #age
is to call it within another method.
Protected Access
This can be a little confusing and is best understood by the following example.
Inside of a class, protected methods are accessible like public methods. When another object of the same class is passed in to an instance method, then that object can access the protected method.
Outside of a class, protected methods act like private methods.
class Person
attr_accessor :name
attr_writer :age def initialize(name)
@name = name
@age = 20
end def ==(other)
age_compare = age == other.age
age_compare ? "same age" : "different age"
end protected
attr_reader :age
endbob = Person.new('Bob')
rob = Person.new('Rob')
rob.age = 10
cobb = Person.new('Cobb')bob.age
=> NoMethodError (protected method...)bob == rob
=> "different age"bob == cobb
=> "same age"
The method ==(other)
is a fake operator. Fake operators and equality are deeper topic that will be covered in another post. We are using it to see if bob
is equal to rob or cobb
but how do you compare to object? Well we have to define what we are comparing, In this case we use the object’s age.
First we see that like a private
method, #age
is not accessible outside of the class with an an object, just like a private method. Where it is similar to a public
method is when inside of a instance method if another object of the same class is passed in, then that object can access the protected method. Hence other.age
returns the person age.
This is a form of encapsulation as we are limiting access to methods and instance variables, if they returned by the method. We can access them if the correct keyword is used, hence obvious intent to change the code.