Like many parts of Ruby that look like special language features, Ruby’s privacy key-
words are actually methods. Yes access modifiers are simple method calls, they don’t create a new scope.
protected are really methods, so they can take parameters. If you pass a Symbol to one of them, that method’s visibility is altered.
In this case, they’re methods of Module . When you call private , protected , or public , the current module (remember that a class is just a special kind of module) changes the rules it applies to newly defined methods from
that point on.
Private and protected methods work a little differently in Ruby than in most other
programming languages. Suppose you have a class called Foo and a subclass SubFoo .
In languages like Java, SubFoo has no access to any private methods defined by Foo .
As seen in the Solution, Ruby provides no way to hide a class’s methods from its sub-
classes. In this way, Ruby’s private works like Java’s protected .
Suppose further that you have two instances of the Foo class, A and B. In languages
like Java, A and B can call each other’s private methods. In Ruby, you need to use a
protected method for that. This is the main difference between private and pro-
tected methods in Ruby.
class Foo private def pri 'hey I am private of Foo' end protected def prot 'Hey I am protected of Foo' end end class SubFoo < Foo def call_pri_of_foo pri end def call_prot_of_foo prot end end
Now calling the accessors within SubFoo
> sub_foo = SubFoo.new => #<SubFoo:0x00000002b56ad8> > sub_foo.call_pri_of_foo => "hey I am private of Foo" > sub_foo.call_prot_of_foo => "Hey I am protected of Foo"
Up to here; there seem to be no difference
next_sub_foo = SubFoo.new => #<SubFoo:0x00000002b1a0b0>
def next_sub_foo.access_private(child_of_sub_foo) child_of_sub_foo.pri end
def next_sub_foo.access_protected(child_of_sub_foo) child_of_sub_foo.prot end
Now calling the accessor
> next_sub_foo.access_private(sub_foo) # => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8> > next_sub_foo.access_protected(sub_foo) # => "Hey I am protected of Foo"