Forum: Ruby Private methods - only available to oneself?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
(Guest)
on 2006-02-11 07:28
(Received via mailing list)
Hi, all.

I'm a somewhat newbie in ruby realm, and trying to write some codes.
Yesterday, I've found very strange characteristics in ruby.

Please see the following:

irb(main):001:0> class Foo
irb(main):002:1> private
irb(main):003:1>   def bar
irb(main):004:2>     print "hi"
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> class Foo
irb(main):008:1> public
irb(main):009:1>   def duh
irb(main):010:2>     f = Foo.new
irb(main):011:2>     f.bar
irb(main):012:2>   end
irb(main):013:1> end
=> nil
irb(main):014:0> f = Foo.new
=> #<Foo:0x2cdd2f0>
irb(main):015:0> f.duh
NoMethodError: private method `bar' called for #<Foo:0x2cdb7a8>
        from (irb):11:in `duh'
        from (irb):15
irb(main):016:0> quit

As you can see in the above, method "bar" is private to Foo. And that
method is called from another public method "duh". "duh" calls private
method of "f", which is not the instance where "duh" is called.

In all other languages, such as Java and C++, it is perfectly legal to
call private method as long as the method is called from methods of
the same class.

For example, the following complies in C++:

#include <iostream>

using namespace std;

class Foo
{
    private:
        void foo()
        {
            cout << "hi" << endl;
        }

    public:
        void duh()
        {
            Foo f;
            f.foo();
        }
};

int main()
{
    Foo f;
    f.duh();
    return 0;
}

I'm not saying that Ruby is wrong while the others are correct. I'm
just trying to figure out the "reason" of this strange behavior. Any
one can tell me?
Kent S. (Guest)
on 2006-02-11 08:18
(Received via mailing list)
The short answer would be: because Ruby is not Java or C++.
The long answer is: in Ruby you can't invoke private methods by using
explicit receiver:

irb(main):001:0> class A
irb(main):002:1> def m; puts 'ok' end
irb(main):003:1> private :m
irb(main):004:1>
irb(main):005:1* def test
irb(main):006:2>   m
irb(main):007:2>   self.m
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> A.new.test
ok
NoMethodError: private method `m' called for #<A:0x3331d0>
        from (irb):7:in `test'
        from (irb):10
        from :0
irb(main):011:0>

Kent.
Minkoo S. (Guest)
on 2006-02-11 10:58
(Received via mailing list)
Thanks, Kent.

Yes, I know that Ruby is neither Java nor C++.

Let me put this way. Private methods should be called by an entity
which understand the internals of the object. Also, the entity will be
tightly coupled with the implementaion details.

In the code I've shown above, private method is called by the class
itself. I believe it is manifest that the class itself can not but
coupled with oneself. In addition, it is also sure that the object
understand the internal structure and implementation details.

That being said, is there still any reason to prohibit such a private
method access?
Erik V. (Guest)
on 2006-02-11 11:43
(Received via mailing list)
Private methods are only callable from within the same objects.
In your, situation, that's not happening. You are calling bar
of one Foo object from another Foo object.

You should use "protected" to "define" that behavior.

See below.

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

----------------------------------------------------------------

 class Foo
 protected
   def bar
     puts "hi"
   end
 end

 class Foo
 public
   def duh
     f = Foo.new
     f.bar
   end
 end

 f = Foo.new
 f.duh

 f = Foo.new
 f.bar          # Should fail...
Minkoo S. (Guest)
on 2006-02-11 11:53
(Received via mailing list)
Erik V. wrote:
> Private methods are only callable from within the same objects.

It does in Ruby. However, Java and C++ allows that if the method is
called from another method which is public.

>  class Foo
>  protected
>    def bar
>      puts "hi"
>    end
>  end
>
>  f = Foo.new
>  f.bar          # Should fail...
>

I agree with you that this code should fail.

I'm not saying that it's incorrect. I want to find out the reason of
design decision.

Best,
Minkoo S.
Phrogz (Guest)
on 2006-02-11 12:28
(Received via mailing list)
The reason of what design decision?

Ruby doesn't have Java's "public" (anyone may access) and "private"
(same-class only), it has one additional level with better names:

public - anyone may access
protected - same class only, please
private - only from the instance itself

"Mom, my brother is messing with my hair! Protect me!"
"Your hair *is* protected, that's the problem. Make it private and then
he won't be able to touch it."
Minkoo S. (Guest)
on 2006-02-11 13:03
(Received via mailing list)
Thank you Phrongz. Now I understand what Erik said.
Erik V. (Guest)
on 2006-02-11 13:44
(Received via mailing list)
Try this:

 f = Foo.new
 f.instance_eval{bar}   # Won't fail... !!!

.... instead of this:

 f = Foo.new
 f.bar                  # Should fail...

Just to confuse you...

> protected - same class only, please

That's why Phrogz said "please".

> private - only from the instance itself

He should have said "please", again.

gegroet,
Erik V. - http://www.erikveen.dds.nl/
Minkoo S. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
Okay. Now I got totally confused. What's the purpose of instance_eval?
Erik V. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
> > f.instance_eval{bar} # Won't fail... !!!
>
> Okay. Now I got totally confused. What's the purpose of
> instance_eval?

Instance_eval evaluates the given block within the context of
the receiver. This means that bar is called from within the
context of f itself.

(You should have asked: "If we can do this, what's the purpose
of 'protected' or 'private'?"...)

gegroet,
Erik V. - http://www.erikveen.dds.nl/
Minkoo S. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
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'?"

Thanks in advance.

Best,
Minkoo S.
Minkoo S. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
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.

Yes, what I did want to know is "If we can do this, what's the purpose
of 'protected' or 'private'?"

Best,
Minkoo S.
James B. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
Minkoo S. wrote:
...
> "If we can do this, what's the purpose of 'protected' or 'private'?"

To let you know when code is being used contrary to its design.  The
idea is not to make things impossible, but to facilitate intention.

If you unwittingly call a private method, Ruby complains.  But if you
still believe you have a good reason to call it, Ruby makes it possible.

Ruby assumes the developer is a grown-up.


--
James B.

"Blanket statements are over-rated"
Hal F. (Guest)
on 2006-02-24 19:46
(Received via mailing list)
Minkoo S. 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
James B. (Guest)
on 2006-02-24 21:51
Hal F. wrote:
> Minkoo S. 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.

i.e

Class Foo

def foo_one
  bar
end

def foo_two
  self.bar
end

def bar
  puts "In Bar"
end

private  :bar

end

f = Foo.new

f.foo_one
-> "In Bar"

f.foo_two
-> NoMethodError: private method `bar' called for

This leads to the inference that self !=== <implicit self> which strikes
me as decidedly odd.  Self is either always self or it is not and if not
then what is it? Whether self is declared as the the receiver or left
for the interpreter to contextually establish should make no difference
to the effect of a private method.  Is this difference due to a parsing
limitation or a purposeful design decision that serves some intent I
cannot presently fathom?  If the latter, then what is the purpose served
by this disticntion between an explicit and implicit self receiver?
unknown (Guest)
on 2006-02-24 23:00
(Received via mailing list)
Hi --

On Sat, 25 Feb 2006, James B. wrote:

>> 'private' is not like a locked door. It is like a sign saying "Do Not
> distinguishes between implicit and explict calls to self.
>  self.bar
> f = Foo.new
> for the interpreter to contextually establish should make no difference
> to the effect of a private method.  Is this difference due to a parsing
> limitation or a purposeful design decision that serves some intent I
> cannot presently fathom?  If the latter, then what is the purpose served
> by this disticntion between an explicit and implicit self receiver?

I'm mostly guessing, but I imagine because it would be hard to
establish that exception to the rule, and the exception would serve no
purpose.  Also, I think of self as a *representation* of the current
object.  So when the interpreter sees:

   x

it doesn't literally stick "self" on the front; it just sends the
message to the current object.


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
E. Saynatkari (Guest)
on 2006-02-24 23:14
James B. wrote:
> Hal F. wrote:
>> Minkoo S. 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
James B. (Guest)
on 2006-02-24 23:35
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
Jim W. (Guest)
on 2006-02-24 23:58
James B. 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 W.
E. Saynatkari (Guest)
on 2006-02-25 00:45
James B. 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
Erik V. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
> 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... :)

> 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 (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
Gene T. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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, ...)

http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9
unknown (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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 :-)


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
Yukihiro M. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
Hi,

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

Do you mean you are expecting funcall's vanishment?

							matz.
unknown (Guest)
on 2006-02-26 16:33
(Received via mailing list)
Hi --

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

> |I think there's still hope that that will disappear by 2.0 :-)
>
> 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 :-)


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
Jacob F. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
On 2/11/06, Gene T. <removed_email_address@domain.invalid> 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.
Jacob F. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
On 2/11/06, Jacob F. <removed_email_address@domain.invalid> 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.
Adam P. Jenkins (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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
Daniel N. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
unknown (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
Adam P. Jenkins (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.

>
> 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
Adam P. Jenkins (Guest)
on 2006-02-26 16:33
(Received via mailing list)
removed_email_address@domain.invalid 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
unknown (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
Minkoo S. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
I don't think the following statement make sense.

removed_email_address@domain.invalid 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.
Minkoo S. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
removed_email_address@domain.invalid 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.
unknown (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
David V. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
Minkoo S. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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.
David V. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
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. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
Also, a minor mental exercise just came to mind. Presuming Ruby private
would
work like in C++, consider this code snippet:

	class A
		def foo
			puts "foo"
		end
		private :foo
	end

	a = A.new
	b = A.new

	def b.bar
		foo
	end

Should this be valid? Is b an instance of the same class as a? If not,
should
the call to #foo still be valid or not? (E.g. should we consider
singleton
classes in the method access rules?)

On a slightly related note, in case people watching the thread aren't
confused
enough as it is: Ruby's private methods are actually accessible from
subclasses.

In any case, I think determining anything based on the notion of "the
same
class" in Ruby would only lead to more ambiguity in the language rather
than
make it easier to comprehend. It would also seem very non-rubyish to me,
since as opposed to the C++ language family, a class is not the only, or
sometimes even not even an important element of defining an object's
behaviour.

David V.
Robert K. (Guest)
on 2006-02-26 16:33
(Received via mailing list)
David V. wrote:
> a = A.new
> b = A.new
>
> def b.bar
> foo
> end
>
> Should this be valid? Is b an instance of the same class as a? If
> not, should the call to #foo still be valid or not? (E.g. should we
> consider singleton classes in the method access rules?)

It's valid.  And it should be IMHO.

> On a slightly related note, in case people watching the thread aren't
> confused enough as it is: Ruby's private methods are actually
> accessible from subclasses.

.... and superclasses:

irb(main):001:0> class Base
irb(main):002:1> def foo() bar() end
irb(main):003:1> end
=> nil
irb(main):004:0> class Der < Base
irb(main):005:1> def bar() "bar!" end
irb(main):006:1> private :bar
irb(main):007:1> end
=> Der
irb(main):008:0> Der.new.foo
=> "bar!"
irb(main):009:0>

> In any case, I think determining anything based on the notion of "the
> same class" in Ruby would only lead to more ambiguity in the language
> rather than make it easier to comprehend.

The appropriate term when it comes to private methods is "the same
instance". :-)

> It would also seem very
> non-rubyish to me, since as opposed to the C++ language family, a
> class is not the only, or sometimes even not even an important
> element of defining an object's behaviour.

Definitely!

Kind regards

    robert
Jim W. (Guest)
on 2006-02-26 20:32
It is good to ask questions to come to a better understanding.  With
that in mind...

Minkoo S. wrote:
> 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?

In Ruby, the question "What class does this belong to?" tends to be
deemphasized in favor of "What does this object do?".  Considering that
point of view tells me that instance based protection is not out of
place at all in the Ruby scheme of things.

Also, Ruby's instance based protect is not unique.  The protection
scheme in Eiffel is instance based as well.

--
-- Jim W.
This topic is locked and can not be replied to.