Ruby Visibility : public, private and protected

Now a days I have started learning Ruby and/ Rails because my new job requires these languages. While programming in Ruby, it feels so natural and syntax of Ruby is much cleaner compared to other programming languages that i did in the past. However there are few confusing things in Ruby when you come from other programming languages such as Java, C#, C++ etc. One of those things are methods visibility in Ruby. In Ruby every methods are public by default.

class Foo

  def say_hello
  	puts "Hello World"
  end

  def say_bye
  	puts "Good Bye"
  end

end

now in above code both the methods “say_hello” and “say_bye” are public by default so if i create object of Foo class and call methods “say_hello” and “say_bye” it will work as expected


foo = Foo.new
foo.say_hello    # will print "Hello Wolrd"
foo.say_bye      # will print "Good bye"

Now lets make method “say_bye” to private, in Ruby to make any method private we write keyword private and then define methods underneath the word private. Any method written after word “private” will all be private

class Foo

  def say_hello
  	puts "Hello World"
  end

  private

  def say_bye
  	puts "Good Bye"
  end

end

foo = Foo.new
foo.say_hello    # will print "Hello Wolrd"
foo.say_bye      # Error: calling private method

So far everything is working as expected. We know that we can’t call method “say_bye” directly on foo object because “say_bye” is private method but we can call method “say_bye” inside “say_hello” method. So far nothing new. Now lets create another class called “Bar” which will inheritance from “Foo” class


class Bar < Foo

  def say_bar
  	puts "I am bar."
  end

end
bar = Bar.new
bar.say_bar     # will print "I am bar."

Now from langauges like Java, we know that during inheritance, child class will inherit public and protect methods from parent class. But in Ruby it’s different, in Ruby child class also inherit private methods as well. To demonstrate this concept lets call private method “say_bye” of “Foo” class inside “Bar” class

class Bar < Foo

  def say_bar
  	puts "I am bar."

  	say_bye
  end

end
bar = Bar.new
bar.say_bar      # will print "I am bar."
                 # Good Bye"

If we see the result we print out “I am bar” and “Good Bye”.This shows that in Ruby child class inherite private method from parent class. You can call those private methods inside your class but you can not call them on object. Code show below will not work because you are trying to invoke private method directly on the object.

bar = Bar.new
bar.say_bye   # Error     

Another surprising feature of Ruby which i haven’t seen in languages like Java is, even you make your methods private, you can still force it and call it as public. Ruby understands that’s its programmers responsibility to know what they are doing. It allows method to be private but if programmers still want to invoke private methods then Ruby won’t stop programmers from doing so. We can invoke private methods by using “:send”.


foo = Foo.new
foo.say_hello       # will print "Hello Wolrd"
foo.send(:say_bye)  # will print "Good Bye"


bar = Bar.new
bar.say_bar         # will print "I am bar."
bar.send(:say_bye)  # will print "Good Bye"

Advertisements

One thought on “Ruby Visibility : public, private and protected

  1. I blog often and I really appreciate your
    content. This article has truly peaked my interest.
    I am going to take a note of your website and keep checking for new information about
    once a week. I subscribed to your Feed too.

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