Access Modifiers

5 Min. Read
Aug 25, 2019

Introduction

Ruby’s access Modifiers such as private, public, or protected are actually methods and take parameters. If you pass a Symbol to one of them, that method’s visibility is altered. And according to the visibility that is assigned to the methods they can be either called internally within a class or externally with explicit receivers, for example: receiver.hello

Comparison between Java and Ruby

For users having background in Java, the private and protected method works somewhat different that what you might expect. In Java the inherited class that inherits the superclass has no access to the private methods of the superclass, whereas, in ruby the inherited class does. For example:

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Person
{
  int age;

  Person(int age)
  {
  this.age = age;
  }

  private void showAge()
  {
  System.out.println("Age is: " + age);
  }
}

class Student extends Person
{
  Student(int age)
  {
    super(age);
  }
  public void getAge()
  {
    super.showAge();
  }
}

public class Main
{
  public static void main(String args[]){
  Student s = new Student(12);
  s.getAge();
  }
}

The super classes showAge() is wrapped and called from within the public method in the child class.

The above code gives the following message:

Main.java:24: error: showAge() has private access in Person super.showAge();

On the other hand, in case of Ruby the same program would let the inherited class gain access to the private method in the super class. For example:

In Ruby

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person
  def initialize age
    @age = age
  end
  private
    def getAge
      printf "Age is: %s",@age
    end
end
class Student < Person
  def showAge
    getAge
  end
end

s = Student.new(12)
s.showAge

Here, the child class Student is able to call the private method getAge of the super Class Person, by wrapping the private method inside it’s public method.

Access Modifiers in Ruby:

1. Private:

As seen above, in ruby private methods of the super class can be called by it’s inherited class.

NOTE: Neither in Java or Ruby can you call the private method outside of the class using an object as an explicit receiver. In this case,

1
2
Person p = new Person(12);
p.getAge()

in Java, and

1
2
p = Person.new()
p.getAge

in Ruby

Where, getAge is a private method, would throw error.

Talking About Ruby,

The methods declared private in Ruby can only be accessed by wrapping them within public methods in the parent class or their children classes.

The private methods cannot be called directly from outside of these classes (Parent and Child) using objects of classes as a explicit receiver. Eg: p = Person.new(22); p.getAge; #Where getAge is a private method

The receiver is always implicitly self(it’s defining class) when a private method is called. ie. private method cannot be called by an explicit receiver (object). It can only be called implicitly using self.

Case I: The private method being called from within the same class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person
  def initialize age
    @age = age
  end
  def showAge
    getAge
  end
  private
    def getAge
    printf "Age is: %s",@age
  end
end

p = Person.new()
p.showAge

Output:

Age is: 12

The private method is wrapped around the public method so that it can be called by the instance of the Person class.

Case II: The private method being called from an inherited class:

We are going to use the same example that we’ve used in the beginning of the blog.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person
    def initialize age
      @age = age
    end
    private
      def getAge
        printf "Age is: %s",@age
      end
end

class Student < Person
    def showAge
      getAge
    end
end

s = Student.new(12)
s.showAge

We can see that, instance of child class Student is able to access the private method of the super class, after wrapping the private method in it’s public method.

2. Public:

On the contrary, the methods defined public can be called from within a class and can also be called outside of the class definition by the use of an instance of the Class which cannot be done for a private method.

For Example:

1
2
3
4
5
6
7
8
9
10
11
12
class Person
  def initialize age
    @age = age
  end
  public
    def getAge
      printf "Age is: %s",@age
    end
end

p = Person.new(12)
p.getAge

If getAge were to be private in this case, we would not be able to call the getAge method, and would get a runtime error.

NOTE: A method is public by default, if not stated otherwise.

Case I: Public method called within the class itself

1
2
3
4
5
6
7
8
9
10
class Person
  def initialize age
    @age = age
  end
  def getAge
    printf "Age is: %s",@age
  end
end
p = Person.new(22)
p.getAge

This is as simple as it gets. The instance of the Person class can directly call it’s public getAge method, without having it wrapped around any other methods.

Case II: Public method accessed from an inherited class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person
  def initialize age
    @age = age
  end
  def getAge
    printf "Age is: %s",@age
  end
end

class Student < Person
end

s = Student.new(22)
s.getAge

We can see that the child class Student is able to call the getAge method as if it were it’s own, without having to wrap it in any of it’s public methods.

3. Protected

Protected shows same behavior in both the cases (Case-I and Case-II) as a Private method does.

Private and Protected methods are for internal usage, and can only be called externally within a public method.

The main difference between private and protected methods is that, protected methods can be called with, or without, an explicit receiver, but that receiver is always self (it’s defining class) or an object that inherits from self.

Summary:

You define a method as private if you only want to use it internally, inside the class, and you don’t want it to be called externally, by objects, unless it’s within a public method that has access to that private method.