Private methods - only available to oneself?

James Byrne wrote:

Hal Fulton wrote:

Minkoo Seo wrote:

Thanks, Erik. I'm afraid that I'm not a native English spearker, so
sometimes it's not easy to express my own idea in exact English
expression.

Of course, I did look up the reference and found what instance_eval
does when being called. What I tried to ask was, as you stated,
"If we can do this, what's the purpose of 'protected' or 'private'?"

'private' is not like a locked door. It is like a sign saying "Do Not
Enter.'

Or look at it this way: It makes it "more difficult" to access private
vars (so that you will know you shouldn't), but doesn't make it
impossible (in case you really, really need to).

Hal

I do not understand why within the class definiton the Ruby interpreter
distinguishes between implicit and explict calls to self.

Think of the self.foo call just accessing an object called
'self'--sure, it is actually the same object, but you could
just as well replace 'self' with the external variable name.
You are still sending a message to an explicit receiver, which
is not possible in Ruby for any private methods (except for the
self.foo = 5, where it is required).

<snip, rforum />

E

···

--
Posted via http://www.ruby-forum.com/\.

James Byrne wrote:

I do not understand why within the class definiton the Ruby interpreter
distinguishes between implicit and explict calls to self.

Possibly because it allows you[1] to examine the code and statically
determine if a private method is allowed. If the implicit receiver rule
were not used, then is the following a valid use of a private method?

   def f(other)
     other.private_method
   end

Well, maybe or maybe not. It depends how it is called.

   f(self) # private method inside of f is ok
   f(you) # private method inside of f is probably not ok,
              # (but it really depends on the value of you, doesn't it)

By using the implicit receiver rule, we know for sure that calling
"private_method" in f is not ok. Less ambiguity.

BTW, the Eiffel language also uses instance based protection (like Ruby)
and also uses the implicit receiver rule as well. So there is
precedent.

···

--
-- Jim Weirich

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Sun, 12 Feb 2006, Gene Tani wrote:

Phrogz wrote:

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.

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:

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light (http://www.rubypowerandlight.com)

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

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 Fugal

···

On 2/11/06, Gene Tani <gene.tani@gmail.com> wrote:

Phrogz wrote:
>
> 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.

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, ...)

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 2/13/06, Adam P. Jenkins <thorin@theshire.com> wrote:

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

--
-Dan Nugent

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 Wright

···

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

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?

E. Saynatkari wrote:

Think of the self.foo call just accessing an object called
'self'--sure, it is actually the same object, but you could
just as well replace 'self' with the external variable name.
You are still sending a message to an explicit receiver, which
is not possible in Ruby for any private methods (except for the
self.foo = 5, where it is required).

Which is why I do not understand the purpose of the distinction between
implicit and explict self. Both cases are simply references. Why does
the interpreter not simply check the reciever object id for === self
when accessing private methods? Where the context cannot determine
intent with resict to assignment (ie foo = "value" is a variable
reference but self.foo = "value" is a call to private method foo=) then
self obviously must be provided, but why must it NOT be provided
otherwise? This makes no sense to me unless it is due a parsing or
other implementation limitation of the interpreter.

If that is the case, well then so be it. What I am interested in
discovering is whether or not their exists a lexical or grammerical
reason for why self is not permitted as an explicit receiver for private
methods except for cases of foo=, where it is then required.

Regards,
Jim

···

--
Posted via http://www.ruby-forum.com/\.

Hi,

···

In message "Re: Private methods - only available to oneself?" on Sun, 12 Feb 2006 02:19:27 +0900, dblack@wobblini.net 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.

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

Jacob Fugal

···

On 2/11/06, Jacob Fugal <lukfugl@gmail.com> wrote:

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

Daniel Nugent 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.

2) 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

gwtmp01@mac.com wrote:

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?

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

···

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

I don't think the following statement make sense.

gwtmp01@mac.com 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 Seo

James Byrne wrote:

E. Saynatkari wrote:

Think of the self.foo call just accessing an object called
'self'--sure, it is actually the same object, but you could
just as well replace 'self' with the external variable name.
You are still sending a message to an explicit receiver, which
is not possible in Ruby for any private methods (except for the
self.foo = 5, where it is required).

Which is why I do not understand the purpose of the distinction between
implicit and explict self. Both cases are simply references. Why does
the interpreter not simply check the reciever object id for === self
when accessing private methods? Where the context cannot determine
intent with resict to assignment (ie foo = "value" is a variable
reference but self.foo = "value" is a call to private method foo=) then
self obviously must be provided, but why must it NOT be provided
otherwise? This makes no sense to me unless it is due a parsing or
other implementation limitation of the interpreter.

Conceptually, self.foo= should not require the 'self' part but it
is present for the sole benefit of the parser/lexer.

So, 'self' is an *external* reference to 'this object'.

If that is the case, well then so be it. What I am interested in
discovering is whether or not their exists a lexical or grammerical
reason for why self is not permitted as an explicit receiver for private
methods except for cases of foo=, where it is then required.

Regards,
Jim

E

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Sun, 12 Feb 2006, Yukihiro Matsumoto wrote:

Hi,

In message "Re: Private methods - only available to oneself?" > on Sun, 12 Feb 2006 02:19:27 +0900, dblack@wobblini.net 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?

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 (dblack@wobblini.net)
Ruby Power and Light (http://www.rubypowerandlight.com)

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

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 Wright

···

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:

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 Vallner

gwtmp01@mac.com 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).

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 Seo

···

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

David Vallner 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 Seo

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 Wright

···

On Feb 14, 2006, at 11:08 AM, Minkoo Seo 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.

Hi --

David Vallner 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.

There's no contradiction or conflict between the dynamism of Ruby and
the existence of the (largely advisory) "private" access level. You
can always get an object to call a private method (with send), or even
open up the class and change the access level. In other words, the
private status of a method can also be changed anytime, just like the
other things you've mentioned. (I don't know why one would do it, but
one could.)

David

···

On Wed, 15 Feb 2006, Minkoo Seo wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light (http://www.rubypowerandlight.com)

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