# Private methods not so private?

**URL:** <https://www.ruby-forum.com/t/private-methods-not-so-private/111018>\
**Category:** Ruby\
**Created:** [August 2, 2007, 12:02am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018 "2007-08-02T00:02:41Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 12:02am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/1 "2007-08-02T00:02:41Z")

</div>

Hello,  
I’m using Ruby 1.8.2 and I’m reading the book “Programming Ruby 2nd  
edition”. In this book they say, that Ruby implements private methods by  
not allowing another receiver than “self”. After reading this, I tried  
the following:

class Test  
private  
def print\_hello  
puts “Hello everyone!”  
end  
end

t = Test.new  
t.send( “print\_hello” )

This program runs just fine and prints “Hello everyone!”.

Is this behaviour to be expected?

Turing

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 12:10am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/2 "2007-08-02T00:10:33Z")

</div>

Frank M. wrote:

> end  
> Is this behaviour to be expected?  
> Yes - send trumps private. Private in Ruby is more of a guideline than  
> a rule. The implementer is trying to tell you not to go there, but you  
> can get around it if you really need to.

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 12:11am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/3 "2007-08-02T00:11:33Z")

</div>

On Thu, Aug 02, 2007, Frank M. wrote:

> This program runs just fine and prints “Hello everyone!”.
> 
> Is this behaviour to be expected?

Yes. send bypasses protection levels, for reasons I’m not really clear  
on. If I were to hazard a guess, it would be that what you send is  
eval’ed inside the context of the object, thereby making self the  
receiver, but that’s a total guess.

Test.new.print\_hello will cause the error you expect.

As a sidenote, upgrade your ruby 😉

Ben

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 2:43am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/4 "2007-08-02T02:43:43Z")

</div>

On Aug 1, 4:06 pm, Alex Y. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > puts “Hello everyone!”  
> > Yes - send trumps private. Private in Ruby is more of a guideline than  
> > a rule.

It’s a guideline in any language.

I think people tend to think of ‘private’ as some sort of security  
enforcement. It’s not. It just means, “You aren’t supposed to access  
this method directly. If you go out of your way to do so, I am not  
responsible for the consequences”.

The advantage of allowing send to access private methods is that it  
allows you to test private methods. 🙂

Regards,

Dan

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 10:43am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/5 "2007-08-02T10:43:21Z")

</div>

Ben B. wrote:

> > 
> 
> As a sidenote, upgrade your ruby 😉
> 
> Ben

Ben,

It is always possible to run private methods, change class variables,  
etc. The way to do it is to reopen the class (or add an instance method)  
that calls the private method or sets/gets the variable we need. Since  
it’s possible, why not make it easier? Ruby tries not to impose on what  
the user can do, so we have foo.send, foo.instance\_variable\_set, and  
foo.instance\_variable\_get.

Dan

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 4:45am UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/6 "2007-08-02T04:45:54Z")

</div>

On Aug 1, 5:42 pm, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > This program runs just fine and prints “Hello everyone!”.
> 
> > > Is this behaviour to be expected?
> 
> > Yes - send trumps private. Private in Ruby is more of a guideline than  
> > a rule.
> 
> It’s a guideline in any language.
> 
> I think people tend to think of ‘private’ as some sort of security  
> enforcement. It’s not.

It is in C++ and Java, maybe even VB, if I recall… (I try not to  
recall VB).  
Well, maybe not a “security enforcement” but a visibility and/or  
invocation restriction.

My JVM even gives me an IllegalAccessException when I try to access an  
private Method at runtime via reflection.

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 1:43pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/7 "2007-08-02T13:43:48Z")

</div>

Le jeudi 02 août 2007 à 20:28 +0900, “Jørgen P. Tjernø” a écrit :

> -----END PGP SIGNATURE-----

It is a root of bad practices, but it may be necessary… I think a good  
principe is : use public methods only of others’s libraries, and use  
instance\_eval (etc) of yours when you need it, and if there is  
collaboration between classes (like friendly classes of C++).  
Thus you will be able to keep your model safe.

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 1:29pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/8 "2007-08-02T13:29:46Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Daniel B. wrote:

> [… snip …]  
> The advantage of allowing send to access private methods is that it  
> allows you to test private methods. 🙂  
> Isn’t that a Bad Practice ™? Private methods are mostly meant for the  
> internals of a class, and a test should really only test how the class  
> interacts with the rest of the world - right? (i.e. public methods)

I might’ve missed the whole point, so this post contains Many  
Questionmarks. 😉

Kindest regards, Jørgen P.  
Tjernø.-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.6 (GNU/Linux)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iD8DBQFGsbDiUMzc1WGo4zgRAoJ3AJ9MtInhJTZS9Uq1ABXwxxN9rwkeVACffYBG  
+iCp8nwruwSH/WzNSAsbQp8=  
=ndYq  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 5:13pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/9 "2007-08-02T17:13:27Z")

</div>

On Thu, Aug 02, 2007, Dan Z. wrote:

> the user can do, so we have foo.send, foo.instance\_variable\_set, and  
> foo.instance\_variable\_get.

Right. I was just trying to answer the original question 🙂

Ben

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 1:45pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/10 "2007-08-02T13:45:48Z")

</div>

Hi –

On Thu, 2 Aug 2007, “Jørgen P. Tjernø” wrote:

> -----BEGIN PGP SIGNED MESSAGE-----  
> Hash: SHA1
> 
> Daniel B. wrote:
> 
> > [… snip …]  
> > The advantage of allowing send to access private methods is that it  
> > allows you to test private methods. 🙂  
> > Isn’t that a Bad Practice ™? Private methods are mostly meant for the  
> > internals of a class, and a test should really only test how the class  
> > interacts with the rest of the world - right? (i.e. public methods)

No; you definitely want to test your private methods too. First of  
all, if you’re writing a class, you need to test its internals;  
nothing should be a “black box” for the tests. Second, private  
methods are actually available to the world, even without send. They  
just have to be called the right way:

puts “Hi”  
class C  
attr\_accessor :x  
end  
C.class\_eval { define\_method “y” }

puts, attr\_accessor, and define\_method are all private, but you’d  
certainly want to test them if you had written them.

David

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 8:00pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/11 "2007-08-02T20:00:30Z")

</div>

Hello everybody,  
thanks for your explanations. And I didn’t know that ruby allows the  
reading and setting (and even creation) of instance variables.

What does class\_eval do?

And actually I’m using Ruby 1.8.6 I confused the version number with  
those in the book.

Turing

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 8:39pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/12 "2007-08-02T20:39:06Z")

</div>

On 8/2/07, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > allows you to test private methods. 🙂  
> > > Isn’t that a Bad Practice ™? Private methods are mostly meant for the  
> > > internals of a class, and a test should really only test how the class  
> > > interacts with the rest of the world - right? (i.e. public methods)
> 
> No; you definitely want to test your private methods too.

Conventional wisdom in the Agile/TDD community is that you shouldn’t  
be testing private methods. The reasoning goes something like this:

1. If you’re doing TDD, you’re sending messages to objects that other  
objects in your system will send. The corresponding methods should be  
public.

2. In TDD, private methods appear through refactoring, and therefore  
are already tested implicitly through the tests of public methods.

3. When you feel the need to add tests on private methods (which have  
appeared through refactoring), it should be considered a sign that a  
new object is wanting to be born and should be extracted out into a  
new class.

My sense is that some of this thinking is a product of the fact that  
testing privates in Java means using reflection, resulting in  
refactoring inefficiencies. In Ruby, testing privates is fairly easy  
and we don’t really have the refactoring tools that the Java community  
has, so refactoring in Ruby tends to be much more manual anyhow.

That said, I think the OO design questions that get raised are worthy  
of exploration when you feel the need to test something private.

WDYT?

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 8:59pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/13 "2007-08-02T20:59:10Z")

</div>

I’ve written some interesting use cases concerning send here. FYI: my  
understanding is that 1.9 will change the semantics of send so that it  
no longer accesses private methods.

[http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/644b55fdb9e346f5/98ba46415087de05#98ba46415087de05](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/644b55fdb9e346f5/98ba46415087de05#98ba46415087de05)

Regards,  
Dan

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 8:55pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/14 "2007-08-02T20:55:09Z")

</div>

On Fri, Aug 03, 2007, Frank M. wrote:

> thanks for your explanations. And I didn’t know that ruby allows the  
> reading and setting (and even creation) of instance variables.

Yup. That’s what @something variables are.

> What does class\_eval do?

It’s like instance\_eval, but evaluates in the context of a class  
instead. Hark:

str = “foo”  
str.instance\_eval {length}  
=\> 3 (same as calling str.length)

str.class.class\_eval {def foo; return ‘bar’; end}  
str.foo  
=\> ‘bar’ # effectively the same as re-opening the class

I’m sure there are other subtleties involved, but that’s the top-level  
view.

Ben

---

<div class="post-metadata">

**Author:** ![dizzyone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dizzyone](https://www.ruby-forum.com/u/dizzyone)\
**Post date:** [August 2, 2007, 9:31pm UTC](https://www.ruby-forum.com/t/private-methods-not-so-private/111018/15 "2007-08-02T21:31:13Z")

</div>

Hi –

On Fri, 3 Aug 2007, David C. wrote:

> > > > The advantage of allowing send to access private methods is that it
> 
> 1. If you’re doing TDD, you’re sending messages to objects that other
> 
> My sense is that some of this thinking is a product of the fact that  
> testing privates in Java means using reflection, resulting in  
> refactoring inefficiencies. In Ruby, testing privates is fairly easy  
> and we don’t really have the refactoring tools that the Java community  
> has, so refactoring in Ruby tends to be much more manual anyhow.
> 
> That said, I think the OO design questions that get raised are worthy  
> of exploration when you feel the need to test something private.
> 
> WDYT?

My tendency is to think that the public/private distinction in Ruby  
does not overlap very closely with the line between methods you’re  
likely to use from outside and methods you’re not, mainly for two  
reasons.

First, private instance methods of Kernel, like raise and sprintf:  
these are not behind the black curtain, but are private so as to be  
callable in a receiverless way. I’d expect them to be tested.

Second, quick and frequent scope and self-scope changes:

class C  
define\_method …  
end

etc. define\_method, like raise and sprintf, won’t go away because of  
refactoring; it’s a private method, but part of the interface one is  
expected to use (rather than simply a by-product of the implementation  
of some other such method).

That said, it may be that there are private methods one wouldn’t test,  
namely those that are really part of the black box, where all you  
really need to know is whether the black box produces the right  
answer. But I think that’s just a subset of private methods,  
certainly in core/standard Ruby and quite possibly in other Ruby code.

David
