Private methods - only available to oneself?

G

gwtmp01

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?

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
 
A

Adam P. Jenkins

Daniel said:
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
 
A

Adam P. Jenkins

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
 
G

gwtmp01

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 Wright
 
M

Minkoo Seo

I don't think the following statement make sense.

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
 
M

Minkoo Seo

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
 
G

gwtmp01

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 Wright
 
D

David Vallner

D=C5=88a Utorok 14 Febru=C3=A1r 2006 01:08 Adam P. Jenkins nap=C3=ADsal:
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 /=20
protected smack-dab across an inheritance hierarchy. I accuse the whole=20
thread of having degenerated into pure religion.

David Vallner
 
M

Minkoo Seo

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

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
 
D

dblack

--8323328-1467733335-1139965983=:18344
Content-Type: MULTIPART/MIXED; BOUNDARY="8323328-1467733335-1139965983=:18344"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--8323328-1467733335-1139965983=:18344
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

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

--=20
David A. Black ([email protected])
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
--8323328-1467733335-1139965983=:18344--
--8323328-1467733335-1139965983=:18344--
 
D

David Vallner

D=C5=88a Streda 15 Febru=C3=A1r 2006 01:58 Minkoo Seo nap=C3=ADsal:
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.

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

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

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

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

David Vallner
 
D

David Vallner

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 Vallner
 
R

Robert Klemme

David said:
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?)

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
 
J

James Byrne

Hal said:
'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?
 
D

dblack

Hi --

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?

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 ([email protected])
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

E. Saynatkari

James said:
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
 
J

James Byrne

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
 
J

Jim Weirich

James said:
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.
 
E

E. Saynatkari

James said:
E. Saynatkari wrote:



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
 
J

Jim Weirich

It is good to ask questions to come to a better understanding. With
that in mind...

Minkoo said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top