Private methods - only available to oneself?

I think the purpose of instance_eval is one of those “sharp knife”
things in Ruby. (Some other languages try to protect by not giving you
sharp knives. Ruby gives you sharp knives, and trusts that you know
enough not to hurt yourself.)

In Ruby, you can always use instance_eval to tweak the @instance
variables for an object. Even if ‘private’ and ‘protected’ were
enforced, this means that you can totally break the OOP encapsulation.

  1. Any time you use #instance_eval, you should say to yourself “Damn,
    this is a very sharp knife. I’d better be sure not to cut myself!”
    Especially if you’re messing wih the internals of a class you don’t
    know fully how it works.

  2. If you are writing a class or module for use by others, they will
    have access to the source code, and could rewrite it to allow things
    you didn’t intend. Use ‘protected’ and ‘private’ to indicate when the
    methods should be called under normal circumstances. But it’s not a
    guarantee.

I’m sorry Erik. I’m not native English speaker. So, sometimes
it’s not easy to express what I have in my mind in English.

I ain’t either… :slight_smile:

Yes, what I did want to know is “If we can do this, what’s
the purpose of ‘protected’ or ‘private’?”

Good question. I truly don’t know the answer.

Matz?

gegroet,
Erik V. - http://www.erikveen.dds.nl/

Phrogz wrote:

  1. If you are writing a class or module for use by others, they will
    have access to the source code, and could rewrite it to allow things
    you didn’t intend. Use ‘protected’ and ‘private’ to indicate when the
    methods should be called under normal circumstances. But it’s not a
    guarantee.

There’s a few loopholes around private and protected, e.g. subclass a
class with private methods and declare them public in the subclass, but
one of them is closed in 1.9, you can’t #send private methods anymore
(ok, you can #funcall them, …)

http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9

Hi,

In message “Re: Private methods - only available to oneself?”
on Sun, 12 Feb 2006 02:19:27 +0900, [email protected] writes:

|> There’s a few loopholes around private and protected, e.g. subclass a
|> class with private methods and declare them public in the subclass, but
|> one of them is closed in 1.9, you can’t #send private methods anymore
|> (ok, you can #funcall them, …)
|
|I think there’s still hope that that will disappear by 2.0 :slight_smile:

Do you mean you are expecting funcall’s vanishment?

						matz.

Hi –

On Sun, 12 Feb 2006, Gene T. wrote:

class with private methods and declare them public in the subclass, but
one of them is closed in 1.9, you can’t #send private methods anymore
(ok, you can #funcall them, …)

I think there’s still hope that that will disappear by 2.0 :slight_smile:

David


David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails

Hi –

On Sun, 12 Feb 2006, Yukihiro M. wrote:

|I think there’s still hope that that will disappear by 2.0 :slight_smile:

Do you mean you are expecting funcall’s vanishment?

Yes, kind of. I’m worried that we’ll get a lot of “Which one does
private methods, and which one doesn’t?”, and people will just have to
try to memorize it. The names themselves don’t express the
difference, to me.

But I know you didn’t like my send/send! idea :slight_smile:

David


David A. Black ([email protected])
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! Ruby for Rails

On 2/11/06, Jacob F. [email protected] wrote:

An easier bypass, which I don’t think[1] is closing in 1.9/2.0: reopen
the class.

[1] I don’t have a 1.9 version installed to test it on.

Jacob F.

On 2/11/06, Gene T. [email protected] wrote:

class with private methods and declare them public in the subclass, but
one of them is closed in 1.9, you can’t #send private methods anymore
(ok, you can #funcall them, …)

An easier bypass, which I don’t think[1] is closing in 1.9/2.0: reopen
the class.

galadriel:~$ cat > test.rb
class Foo
private
def bar
puts “bar”
end
end

f = Foo.new
begin
f.bar
rescue
puts “Exception raised”
end

… later …

class Foo
public :bar
end

g = Foo.new
g.bar

galadriel:~$ ruby test.rb
Exception raised
bar

Jacob F.

Phrogz wrote:

  1. Any time you use #instance_eval, you should say to yourself “Damn,
    this is a very sharp knife. I’d better be sure not to cut myself!”
    Especially if you’re messing wih the internals of a class you don’t
    know fully how it works.

The other main thing to be concerned about when accessing private
methods is that their behavior, or even existence, may change in the
next version of the class. Furthermore, except for debugging purposes,
I’d say that if you find yourself needing to access private class
methods from outside the class, it’s because the class in question needs
a redesign, or has a bug.

That said, I do think that Ruby’s decision to make private mean “only
accessible to oneself” as opposed to “only accessible to class members”
is debatable. In fact I don’t see the point of it from a practical
point of view. It seems to me that the main reasons for making methods
private is advertise that a) they’re implementation details that may
change without notice in new versions of the class, and b) they may
require inside knowledge of the class’s workings to use correctly. Both
of these reasons would be just as well served by allowing other
instances of the same class to access private members, so I don’t see
the point of the extra restriction. Anyone?

Adam

Adam, there’s two things here:

  1. When you’re using an object in Ruby, the only way to interact
    with it is to send messages to it. This is uniform across the
    language and a damned good idea if you ask me. Mixing methods with
    accessing fields is a bad idea in my book.

  2. Ruby provides the Java private method access level with protected,
    as mentioned earlier in the thread. Yes, it requires you explicitly
    declare member variables as protected, but if you’re dead set on
    giving objects access to all the instance variables, you can
    definitley do that.

On Feb 13, 2006, at 3:23 PM, Adam P. Jenkins wrote:

extra restriction. Anyone?
Are you saying that the only visibility attributes should be public
vs. protected
as opposed to the current public/protected/private triumvirate?

One reason to support the distinction in Ruby is the existence of
singleton methods. It is possible for an instance to behave differently
than any other instance of the class and as such you might want to
support that different behavior by marking some methods as private.

Gary W.

Daniel N. wrote:

Adam, there’s two things here:

  1. When you’re using an object in Ruby, the only way to interact
    with it is to send messages to it. This is uniform across the
    language and a damned good idea if you ask me. Mixing methods with
    accessing fields is a bad idea in my book.

I’m not intending to talk about mixing methods with accessing fields. I
realize that in Ruby all fields are private in the ruby sense, and I’m
fine with that. I’m only talking about calling methods, or sending
messages, however you want to describe it.

  1. Ruby provides the Java private method access level with protected,
    as mentioned earlier in the thread.

This information is actually incorrect. The Java and Ruby definitions
of “protected” are pretty much the same (minus some package scope stuff
in Java which doesn’t apply to Ruby). From the Pickaxe:

A protected member can be invoked only by objects of the defining class
and its subclasses.

Your description and the earlier post you refer to left out the “and its
subclasses” part. If there are parts of a class I write which I want to
be considered as implementation details, subject to change, then I
surely don’t want subclasses that other people write to use those
features. I want to be able to update my class’s implementation, re-run
the class’s unit tests (which test the class’s public and protected
interface), and as long as nobody has used instance_eval to use private
members, no other code should break. Given that the main use I see for
private is to encapsulate code which I don’t want anything outside this
class to depend on, I don’t see the point of saying objects can only
invoke private methods on themself. It’s the unit of code that I’m
trying to protect from other code, not the object from other objects.

Yes, it requires you explicitly
declare member variables as protected, but if you’re dead set on
giving objects access to all the instance variables, you can
definitley do that.

I’m not dead set on anything, especially since it’s easy to just use
instance_eval if I want to. I’m just suggesting that Ruby’s definition
of private is of debatable use, and seeing if anyone has a good
explanation for why it is the way it is, other than defensive statements
like “'Cause Ruby ain’t Java.”

Adam

On Feb 13, 2006, at 7:08 PM, Adam P. Jenkins wrote:

I wasn’t aware of singleton methods. I thought there were
singleton classes, in which case the C++/Java definition of
private would do just as well, since a particular object would be
the only instance of the singleton class. That is:

Well singleton methods are implemented by tucking them away in a
singleton class
but you don’t have to know about that implementation to utilize the
facility:

a = [1,2,3,4]
b = [5,6,7,8]

def a.sum
inject(0) { |s, x| s + x }
end

a.sum # -> 10
b.sum # NoMethodError exception

I think this all might come into play when you consider ‘class
methods’. In Ruby, classes are
objects and so class methods are really singleton methods associated
with a particular instance
of Class. If you didn’t have Ruby’s concept of private then any
class method could directly
call any other class method (because all classes are instances of
Class).

You also mentioned concern about subclasses gaining access to
implementation details of
a superclass. I think Bertrand Meyer wrote about this in Object
Oriented Software Construction.
If I remember correctly he explained that a subclass has a much more
intimate relationship with
its superclasses than an external client has when using the same
classes through their public API.
The benefits of this closer relationship is access to implementation
details. This is also the
greatest weakness since it increases the coupling between the two
classes. So it is a typical
engineering tradeoff between composition and inheritance as a way to
reuse functionality. If
you craft a class such that its implementation can not be reused via
a subclass then it seems to me
you are making a pre-mature design decision about future classes and
reuse. Why cut off that approach
and why make the subclassed API as rigid as the external client API?

Gary W.

[email protected] wrote:

use correctly. Both of these reasons would be just as well served by
allowing other instances of the same class to access private members,
so I don’t see the point of the extra restriction. Anyone?

Are you saying that the only visibility attributes should be public vs.
protected
as opposed to the current public/protected/private triumvirate?

No, I think the three levels of protection are all useful. I was just
suggesting that in this case, the Java/C++ definition of private makes
more sense to me than the Ruby definition. I was wondering if there was
some reason I’m not thinking of why the Ruby definition makes more
sense, at least for Ruby, or if it’s just what Matz happened to think
of. Basically, to me the main reason for private methods is to protect
implementation details of a class definition from being depended on by
other code, so that I’m free to change these private parts of my class
without breaking other code which depends on the non-private parts of my
class. So I don’t see the point of drawing the protection boundary
around instances of the class, rather than the code which implements
the class.

One reason to support the distinction in Ruby is the existence of
singleton methods. It is possible for an instance to behave differently
than any other instance of the class and as such you might want to
support that different behavior by marking some methods as private.

I wasn’t aware of singleton methods. I thought there were singleton
classes, in which case the C++/Java definition of private would do
just as well, since a particular object would be the only instance of
the singleton class. That is:

a = “Hello”

class <<a
private
def superSecret
“foo”
end

public
def to_s
superSecret + self
end
end

In this case, the superSecret method is private to the “a” object,
whether private follows the C++/Java definition, or the Ruby definition.
The Java definition of private would say that any instance of a.class
can call the superSecret method from one of its methods. However, since
“a” is the only instance of a.class, this amounts to the same thing as
the Ruby definition.

If it is possible to add singleton methods to instances of an existing
class, then I can see why it might make sense to make said singleton
methods private to that object.

Adam

[email protected] wrote:

I think this all might come into play when you consider ‘class
methods’. In Ruby, classes are
objects and so class methods are really singleton methods associated
with a particular instance
of Class. If you didn’t have Ruby’s concept of private then any
class method could directly
call any other class method (because all classes are instances of
Class).

I believe that the class method is implemented transparently in Ruby,
because we do not have to metion ‘private’ to make a certain class
method. Of course, it surely make sense that the class method could not
be impelemented without the notion of private. However, I think class
method example is not a thorough argument for private.

I’m afraid that I still do not follow the line of reasoning. Well, this
might be the result of my heavily java/c++ based way of thinking. I
also do not see any other reason for using private when I code some
programs (not the ruby itself). Why should a certain instance hide
itself from the other instances of the same class? Could anyone give me
an exmple?

Best,
Minkoo S.

I don’t think the following statement make sense.

[email protected] wrote:

One reason to support the distinction in Ruby is the existence of
singleton methods. It is possible for an instance to behave differently
than any other instance of the class and as such you might want to
support that different behavior by marking some methods as private.

For example,

class Foo
end

f1 = Foo.new
f2 = Foo.new

class << f1
def bar
puts “hi”
end
end

f1.bar
f2.bar

In this case, we do not need to declare bar method as private to
support instance dependent behavior. What do you say?

Best,
Minkoo S.

On Feb 14, 2006, at 11:08 AM, Minkoo S. wrote:

I believe that the class method is implemented transparently in Ruby,
because we do not have to metion ‘private’ to make a certain class
method.

I wasn’t suggesting that private was needed to implement class methods
just that Java’s notion of private is not private enough for Ruby’s
object
model.

I’m also not claiming that singleton’s are the only reason for
Ruby’s notion of private–just that they might be a reason.

Gary W.

DÅ?a Utorok 14 Február 2006 01:08 Adam P. Jenkins napísal:

So I don’t see the point of drawing the protection boundary
around instances of the class, rather than the code which implements
the class.

And I don’t see the point of drawing a restriction in Java’s private /
protected smack-dab across an inheritance hierarchy. I accuse the whole
thread of having degenerated into pure religion.

David V.

DÅ?a Streda 15 Február 2006 01:58 Minkoo S. napísal:

Private/protected meaning of Ruby is unique, and I believe some kind of

However, on the other hand, ruby does not allow an instance to access
other instance even if they are the instance of the same class. In this
case, an object is something that can not be easily accessed.

I feel that these two conflict, and need justification.

I don’t see the concept of method access restrictions as anything
standardized. If I have my facts correctly, CLOS didn’t have anything
similar, neither did Smalltalk, nor Perl’s or Python’s object systems
(until
recently for the latter). The C++ line of languages seems to be
consistent in
this, and brief googling indicates this was the same in Simula.

Considering Ruby seems to me far, far closer to the first group of
languages
than the second, I’d just take the access restriction capabilities more
as a
perk than a core feature. Separating public API from the internals,
which you
can do, is more important in my opinion than pettifoggery about how to
separate internals from other internals.

Rule of thumb: use protected for internal interfaces, private for helper
methods for an algorithm. The first gives you all the flexibility you
need
without directly exposing your internals to clients, the latter lets you
split code into bitesize chunks without risking state inconsistency by
accidentally calling strange helper methods from unexpected places.

I want example code where it’s necessary for other instances of the same
class
to access a method while unthinkable of an instance of a subclass to do
so
before I consider this as more than “Why isn’t Ruby like My Favourite
Language?” whining.

David V.

David V. wrote:

Dna Utorok 14 Február 2006 01:08 Adam P. Jenkins napísal:

So I don’t see the point of drawing the protection boundary
around instances of the class, rather than the code which implements
the class.

And I don’t see the point of drawing a restriction in Java’s private /
protected smack-dab across an inheritance hierarchy. I accuse the whole
thread of having degenerated into pure religion.

Private/protected meaning of Ruby is unique, and I believe some kind of
elaboration on that point is needed. What method is accessible from the
outer space is quite important in learning a language, isn’t it?

Let me put this way. On one hand, ruby allows me to redefine or add
methods to a class which I’ve not defined. Also, it is possible to
redefine or add methods to a instance of class. Subclasses can access
parent classes. Moreover, there’s no notion of ‘final(Java)/sealed(C#)’
class in ruby. From this point of view, ruby’s objects are quite
dynamic because they can be changed anytime. If these are the only
characteristics in ruby, I would just happy with it.

However, on the other hand, ruby does not allow an instance to access
other instance even if they are the instance of the same class. In this
case, an object is something that can not be easily accessed.

I feel that these two conflict, and need justification.

Minkoo S.