Ruby-Difference between Public, Private and Protected methods!-Part1

Hello RoR developers! Welcome to my blog spot!

This blog is about Access Control in Ruby with relevant code snippets and is very useful for beginners. Advanced programmers may go through this topic to brush up their basics.

What is Access Control and Why do we need it ?

In order to protect data variables/methods from manipulation by external classes, it has to made accessible or visible to chosen classes. Ruby has 3 types of visibility to protect methods/variables:  Public, Private and Protected. We will look at each one them in detail now.

Public: When a method is declared a public, it means that objects of any class have direct access to it. For example in the below code snippet.

class Account

attr_reader :final_balance, :balance

RI = 0.5

def initialize(balance)

  @balance = balance

  @final_balance = @balance + interest

  final_balance = @final_balance

end

public

  def interest

  p ( @balance * self.class::RI )

  end

public

  def rewards(time)       

@reward_points = interest * time * final_balance * 0.1

p ‘Reward points = ‘,@reward_points

p ‘interest = ‘, interest

  end

 def compare (obj1,obj2)

 if (obj1.interest == obj2.interest)

p ‘true’

  else

p ‘false’

p obj1

p obj2

  end

end

end

class Savings < Account

RI = 0.9

end

class Checking < Account

RI = 0.2

end

class User

end

acc = Account.new(100)

sav = Savings.new(200)

chk = Checking.new(300)

usr = User.new

#Now call the instance method using the objects created and see the output

acc.interest # 50

sav.interest # 180

chk.interest # 60

usr.interest # undefined method for User

we observe that public methods are accessible by objects of the parents class ‘Account’ as well as the child class Savings and Checking.

Private & Protected: When a method is declared under private or protected visibility, it cannot be directly accessed by parent class or any of the sub classes. For example in the above code,suppose if we declare the function interest as private as below:

private  (# or protected)

def interest

p ( @balance * self.class::RI )

end

p acc.interest # no method error

p sav.interest # no method error

p chk.interest # no method error

p usr.interest # no method error

In order to access the private/protected methods of a class, Ruby allows implicit calls to private/protected methods through public methods. For example:

acc.rewards(10) # interest = 180

sav.rewards(5)  # interest = 19200

Checking.new(200).rewards(20) # interest = 40

The private/protected method ‘interest’ is accessed via the public method ‘rewards’ as per the definition below:

def rewards(time)

@reward_points = interest * time * final_balance * 0.1

p ‘Reward points = ‘,@reward_points

p ‘interest = ‘, interest

end

Now the most important question arises, what is the difference between private and protected. To understand this lets test both scenarios for the following code and observe the results:

private

def interest

p ( @balance * self.class::RI )

end

obj1 = Account.new(200)

obj2 = Savings.new(200)

Checking.new(200).compare(obj1,obj2) # Private method interest called for Account, NoMethod Error

Now declare the method interest as protected

protected

def interest

p ( @balance * self.class::RI )

end

obj1 = Account.new(200)

obj2 = Savings.new(200)

Checking.new(200).compare(obj1,obj2)

output:

# “false”

#Account:0x2733e70 @balance=200, @final_balance=300.0>

#Savings:0x2733e28 @balance=200, @final_balance=380.0>

 

This actually worked! but why! lets look at the function definition:

def compare (obj1,obj2)

if (obj1.interest == obj2.interest)

p ‘true’

else

p ‘false’

end

end

Inside the public method compare, obj1 of class Account and obj2 of class Savings makes an explicit/direct call to the method ‘interest’ (obj1.interest abd obj2.interest respectively) which is not permitted by Ruby for private methods. Whereas if the method is declared protected, objects of the parent class and its subclass objects can access the method when called inside a public method. Hence the visibility of private is lesser than a protected method.

I hope this blog was useful to some extent to understand different types of access control and their differences!

Advertisements

1 Comment

Filed under Ruby on Rails

One response to “Ruby-Difference between Public, Private and Protected methods!-Part1

  1. Very nice post written about access control, which many developers get confused with. To simplify it further:

    “private methods are accessible in the context of same object, not even to another object of same class.” For example,

    obj1 = Account.new(200)

    obj2 = Account.new(2000)

    now calling compare would throw error, like “private method `interest’ called for #<Account:0x007ff59b84d8f0 SOME HEX".

    And, protected methods are accessible in the context of objects of same Parent as well as subclasses.

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 )

Google+ photo

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

Connecting to %s