# Question about "protected" and "private"

**URL:** <https://www.ruby-forum.com/t/question-about-protected-and-private/166945>\
**Category:** Ruby\
**Created:** [May 1, 2009, 9:11am UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945 "2009-05-01T09:11:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fasun\_Lau](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Fasun\_Lau](https://www.ruby-forum.com/u/Fasun_Lau)\
**Post date:** [May 1, 2009, 9:11am UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945/1 "2009-05-01T09:11:40Z")

</div>

Hi, all  
I’m reading “Programming Ruby”, and have some questions about  
“protected”  
and “private” of class.

In “Programming Ruby” :

Protected methods can be invoked only by objects of the defining class  
and  
its subclasses. Access is kept within the family.  
Private methods cannot be called with an explicit receiver. Because you  
cannot specify an object when using them, private methods can be called  
only  
in the defining class and by direct descendents within that same object.

The difference between “protected” and “private” is  
fairly subtle, _and is different in Ruby than in most common OO  
languages_. If  
a method is protected, it may be called by any instance of the defining  
class or its subclasses. If a method is private, it may be called only  
within the context of the calling object—it is never possible to  
access  
another object’s private methods directly, even if the object is of the  
same  
class as the caller.

I was tried it with the follow code:

C:\Users\v-fsliu\>ruby -v  
ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]

C:\Users\v-fsliu\>irb  
irb(main):001:0\> class Demo  
irb(main):002:1\> def call1  
irb(main):003:2\> method1 + "Object ID: " + self.object\_id.to\_s  
irb(main):004:2\> end  
irb(main):005:1\>  
irb(main):006:1\* def call2  
irb(main):007:2\> method2 + "Object ID: " + self.object\_id.to\_s  
irb(main):008:2\> end  
irb(main):009:1\>  
irb(main):010:1\* protected  
irb(main):011:1\> def method1  
irb(main):012:2\> "Hello, Ruby! "  
irb(main):013:2\> end  
irb(main):014:1\>  
irb(main):015:1\* private  
irb(main):016:1\> def method2  
irb(main):017:2\> "Hi, Ruby! "  
irb(main):018:2\> end  
irb(main):019:1\> end  
=\> nil  
irb(main):020:0\>  
irb(main):021:0\* class NewDemo \< Demo  
irb(main):022:1\> def newcall  
irb(main):023:2\> newmethod + "Object ID: " + self.object\_id.to\_s  
irb(main):024:2\> end  
irb(main):025:1\>  
irb(main):026:1\* protected  
irb(main):027:1\> def newmethod  
irb(main):028:2\> "Hello, new demo! "  
irb(main):029:2\> end  
irb(main):030:1\> end  
=\> nil  
irb(main):031:0\> demo = Demo.new  
=\> #Demo:0x3ae9284  
irb(main):032:0\> demo.call1  
=\> “Hello, Ruby! Object ID: 30886210”  
irb(main):033:0\> demo.call2  
=\> “Hi, Ruby! Object ID: 30886210”  
irb(main):034:0\> demo.method1  
NoMethodError: protected method `method1' called for #<Demo:0x3ae9284> from (irb):34 from :0 irb(main):035:0> newDemo = NewDemo.new => #<NewDemo:0x3ae2a24> irb(main):036:0> newDemo.newcall => "Hello, new demo! Object ID: 30872850" irb(main):037:0> newDemo.newmethod NoMethodError: protected method`newmethod’ called for  
#NewDemo:0x3ae2a24  
from (irb):37  
from :0  
irb(main):038:0\>

My questions are:

1. It seems that protected methodcalled by any instance of the defining  
class or its subclasses.
2. what’s the different in Ruby than in most common OO languages.

Thanks and best regards!

---

<div class="post-metadata">

**Author:** ![Fasun\_Lau](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Fasun\_Lau](https://www.ruby-forum.com/u/Fasun_Lau)\
**Post date:** [May 1, 2009, 10:50am UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945/2 "2009-05-01T10:50:05Z")

</div>

In most OO languages, private methods can only be called from within the  
defining class.

ie

class MyClass

def method1  
method2  
end

private

def method2  
end  
end

A protected method can also be called from subclasses. So if method2 was  
protected, and MySubClass \< Class, then method2 could be called from  
within MySubClass.

In ruby, private and protected methods can be called by any instance of  
the defining class or its subclasses, but private methods cannot have an  
explicit receiver.

In short, the difference is that protected methods can be called from  
within a class on ANY OBJECT of that class or its subclasses.

See [Zerosum dot org - Medium](http://blog.zerosum.org/2007/11/22/ruby-method-visibility) for more  
details

---

<div class="post-metadata">

**Author:** ![Fasun\_Lau](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Fasun\_Lau](https://www.ruby-forum.com/u/Fasun_Lau)\
**Post date:** [May 1, 2009, 3:27pm UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945/3 "2009-05-01T15:27:17Z")

</div>

Fasun Lau wrote:

> irb(main):020:0\>  
> irb(main):021:0\* class NewDemo \< Demo  
> irb(main):022:1\> def newcall  
> irb(main):023:2\> newmethod + "Object ID: " + self.object\_id.to\_s  
> irb(main):024:2\> end  
> irb(main):025:1\>  
> irb(main):026:1\* protected  
> irb(main):027:1\> def newmethod  
> irb(main):028:2\> "Hello, new demo! "  
> irb(main):029:2\> end  
> irb(main):030:1\> end  
> =\> nil
> 
> irb(main):035:0\> newDemo = NewDemo.new  
> =\> #NewDemo:0x3ae2a24  
> irb(main):036:0\> newDemo.newcall  
> =\> “Hello, new demo! Object ID: 30872850”  
> irb(main):037:0\> newDemo.newmethod  
> NoMethodError: protected method `newmethod’ called for

Your second example would have worked the same if you hadn’t inherited  
from Demo, so it doesn’t demonstrate anything new.

Here are some examples that may prove more illustrative:

class Demo

def democall(obj)  
protected\_meth #d1 is calling this method  
private\_meth #d1 is calling this method

```
obj.protected_meth
obj.private_meth

```

end

protected  
def protected\_meth  
puts “hello from protected\_meth”  
end

private  
def private\_meth  
puts “hello from private\_meth”  
end  
end

d1 = Demo.new  
d2 = Demo.new  
d1.democall(d2)

–output:–  
hello from protected\_meth  
hello from private\_meth  
hello from protected\_meth  
r1test.rb:7:in `call': private method`private\_meth’ called for  
#Demo:0x24dec (NoMethodError)  
from r1test.rb:23

==========

Here is an example with some inheritance thrown in:

class Demo  
protected  
def protected\_meth  
puts “hello from protected\_meth”  
end

private  
def private\_meth  
puts “hello from private\_meth”  
end  
end

class Bird \< Demo  
def birdcall(obj)  
protected\_meth #d1 is calling this method  
private\_meth #d1 is calling this method

```
obj.protected_meth

```

end  
end

b1 = Bird.new  
b2 = Bird.new  
b1.birdcall(b2)

–output:–  
hello from protected\_meth  
hello from private\_meth  
hello from protected\_meth

In a language like C++, private methods are not accessible in a  
subclass, so the call to private\_meth in Bird would cause an error.

Note that self is always the object that called the method. For  
example, in this example b1 is calling the method ‘call’, so inside the  
call method self=b1. And when methods are not called with an object  
name in front of the method, the implicit caller is self. In ruby, they  
call the object that is calling the method “the receiver”.

---

<div class="post-metadata">

**Author:** ![Fasun\_Lau](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Fasun\_Lau](https://www.ruby-forum.com/u/Fasun_Lau)\
**Post date:** [May 1, 2009, 3:46pm UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945/4 "2009-05-01T15:46:13Z")

</div>

7stud – wrote:

> Here is an example with some inheritance thrown in:
> 
> class Demo  
> protected  
> def protected\_meth  
> puts “hello from protected\_meth”  
> end
> 
> private  
> def private\_meth  
> puts “hello from private\_meth”  
> end  
> end
> 
> class Bird \< Demo  
> def birdcall(obj)  
> protected\_meth #d1 is calling this method  
> private\_meth #d1 is calling this method
> 
> ```
> obj.protected_meth
> 
> ```
> 
> end  
> end
> 
> b1 = Bird.new  
> b2 = Bird.new  
> b1.birdcall(b2)
> 
> –output:–  
> hello from protected\_meth  
> hello from private\_meth  
> hello from protected\_meth
> 
> In a language like C++, private methods are not accessible in a  
> subclass, so the call to private\_meth in Bird would cause an error.
> 
> Note that self is always the object that called the method. For  
> example, in this example b1 is calling the method ‘call’, so inside the  
> call method self=b1. And when methods are not called with an object  
> name in front of the method, the implicit caller is self. In ruby, they  
> call the object that is calling the method “the receiver”.

Oh boy. Corrections:

class Demo  
protected  
def protected\_meth  
puts “hello from protected\_meth”  
end

private  
def private\_meth  
puts “hello from private\_meth”  
end  
end

class Bird \< Demo  
def birdcall(obj)  
protected\_meth #b1 is calling this method  
private\_meth #b1 is calling this method

```
obj.protected_meth

```

end  
end

b1 = Bird.new  
b2 = Bird.new  
b1.birdcall(b2)

–output:–  
hello from protected\_meth  
hello from private\_meth  
hello from protected\_meth

In a language like C++, private methods are not accessible in a  
subclass, so the call to private\_meth in Bird would cause an error.

Note that self is always the object that called the method. For  
example, in this example b1 is calling the method birdcall, so inside  
the  
birdcall method self=b1. And when methods are not called with an object  
name in front of the method, the implicit caller is self. In ruby, they  
call the object that is calling the method “the receiver”.

---

<div class="post-metadata">

**Author:** ![Fasun\_Lau](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Fasun\_Lau](https://www.ruby-forum.com/u/Fasun_Lau)\
**Post date:** [May 1, 2009, 12:39pm UTC](https://www.ruby-forum.com/t/question-about-protected-and-private/166945/5 "2009-05-01T12:39:36Z")

</div>

Got it! Thanks very much!

2009/5/1 Shaun K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
