Forum: Ruby OO / Private verse Protected

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.
074597b4e64c139d5e1d51c52e475de2?d=identicon&s=25 Paul D. Kraus (Guest)
on 2006-05-31 20:37
(Received via mailing list)
Can someone give me an example of when a private method would be more
appropaiate then a protected one?

I understand the definition of the two but I don't quit understand the
uses.

A protected method is only accessible from other objects derived from
the
same class.
A private method is basically the same thing but can only be called by
the
current object.

*shrug* how are those two things different.
When would you ever have an instance that is going to call a method from
another instance?
76006c10b0773e69a6fcd70614ac258f?d=identicon&s=25 Joost Diepenmaat (Guest)
on 2006-05-31 20:50
(Received via mailing list)
On Thu, Jun 01, 2006 at 03:35:19AM +0900, Paul D. Kraus wrote:
> *shrug* how are those two things different.
> When would you ever have an instance that is going to call a method from
> another instance?

Personally, I think protected methods are completely useless, except
_maybe_
if you want to allow some "dirty" access to improve performance in very
specific cases.

If your methods are supposed to be called from other instances
you're almost always better off making the methods public - if that
makes
your API ugly, you've usually got a bad design.

Joost.
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2006-05-31 20:53
(Received via mailing list)
On May 31, 2006, at 1:35 PM, Paul D. Kraus wrote:

> by the
> current object.
>
> *shrug* how are those two things different.
> When would you ever have an instance that is going to call a method
> from
> another instance?

Maybe in a situation like:

 >> class MyClass
 >>   def initialize
 >>     @secret_data = 5
 >>   end
 >>   def ==( other )
 >>     secret_data == other.secret_data
 >>   end
 >>   protected
 >>   attr_reader :secret_data
 >> end
=> nil

James Edward Gray II
5c4e57ad9f066e56297a60b4a1daa1d3?d=identicon&s=25 Alexandru Popescu (Guest)
on 2006-05-31 20:56
(Received via mailing list)
I think you are looking at the problem from the wrong perspective: is
not calling a method from another instance, but is about were the
method is defined. The protected/private access modifiers are quite
usefull when dealing with class hierarchies.

./alex
--
.w( the_mindstorm )p.
5c4e57ad9f066e56297a60b4a1daa1d3?d=identicon&s=25 Alexandru Popescu (Guest)
on 2006-05-31 21:00
(Received via mailing list)
At least in Java these modifiers are quite usefull: a protected method
is one that offers extensibility/polymorphic behavior for hierarchies,
without exposing it as public API. So the behavior may vary according
to the implementation, and the exposed API/public methods are a
completely different thing.

./alex
--
.w( the_mindstorm )p.
76006c10b0773e69a6fcd70614ac258f?d=identicon&s=25 Joost Diepenmaat (Guest)
on 2006-05-31 21:19
(Received via mailing list)
On Thu, Jun 01, 2006 at 03:57:08AM +0900, Alexandru Popescu wrote:
> At least in Java these modifiers are quite usefull: a protected method
> is one that offers extensibility/polymorphic behavior for hierarchies,
> without exposing it as public API. So the behavior may vary according
> to the implementation, and the exposed API/public methods are a
> completely different thing.

That's only true if you also find some way to stop the "public" from
inheriting from your base classes too, and I cann't think of any
language
that allows you to do that.

Protected methods *are* part of the public API anyway - might as
well admit it and make them public and put a big disclaimer in the
docs.

Joost.
5c4e57ad9f066e56297a60b4a1daa1d3?d=identicon&s=25 Alexandru Popescu (Guest)
on 2006-05-31 22:08
(Received via mailing list)
On 5/31/06, Joost Diepenmaat <joost@zeekat.nl> wrote:
>
> Protected methods *are* part of the public API anyway - might as
> well admit it and make them public and put a big disclaimer in the
> docs.
>
> Joost.
>

Not sure I am getting your argument. For inheritance this is the exact
needed behavior. Any external object will still be not able to call
these methods. So they are providing a way to customize your internal
implementation when working with hierarchies, but not offer it as an
API method.

./alex
--
.w( the_mindstorm )p.
76006c10b0773e69a6fcd70614ac258f?d=identicon&s=25 Joost Diepenmaat (Guest)
on 2006-05-31 23:23
(Received via mailing list)
On Thu, Jun 01, 2006 at 04:29:59AM +0900, Alexandru Popescu wrote:
> >that allows you to do that.
> these methods. So they are providing a way to customize your internal
> implementation when working with hierarchies, but not offer it as an
> API method.

My argument was that you then have to disallow people from implementing
their own classes based on your classes, because if they do, they still
can call the protected methods you just worked so hard to "protect".

My main point though, is that if you think you need protected methods
you
should think really hard about wether other classes might find those
methods useful too (i.e. just make them public instead).

I've ran into too many problems with libraries where you just can't call
very handy methods because the designer decided you shouldn't and then
it
takes hours to work around that. My gut feeling is that protected
methods
are usually either badly designed, or made so the designer can feel good
about not binding the API to the implementation. If your implementation
is
so bad you don't want _other_ people relying on it, but _you_ still need
access to it to make your code work, you're doing something wrong.

I'm open to the idea that protected methods can be useful, it's just
that
I don't like most uses of them that I've seen.

I feel the same about "friend" functions & classes in C++ (harcore
performance reasons only, I'd say)

YMMV,

Joost.
5c4e57ad9f066e56297a60b4a1daa1d3?d=identicon&s=25 Alexandru Popescu (Guest)
on 2006-05-31 23:39
(Received via mailing list)
On 6/1/06, Joost Diepenmaat <joost@zeekat.nl> wrote:
> > >inheriting from your base classes too, and I cann't think of any language
> > needed behavior. Any external object will still be not able to call
> > these methods. So they are providing a way to customize your internal
> > implementation when working with hierarchies, but not offer it as an
> > API method.
>
> My argument was that you then have to disallow people from implementing
> their own classes based on your classes, because if they do, they still
> can call the protected methods you just worked so hard to "protect".
>

But I haven't worked on protecting them against overridding, but
against direct calls. Big difference.

> My main point though, is that if you think you need protected methods you
> should think really hard about wether other classes might find those
> methods useful too (i.e. just make them public instead).
>

This is a matter of the API designer skills. However making everything
public, for the sake that somebody may find one of the methods usefull
is imo worse than having to evolve your initial API.

> I've ran into too many problems with libraries where you just can't call
> very handy methods because the designer decided you shouldn't and then it
> takes hours to work around that. My gut feeling is that protected methods
> are usually either badly designed, or made so the designer can feel good
> about not binding the API to the implementation. If your implementation is
> so bad you don't want _other_ people relying on it, but _you_ still need
> access to it to make your code work, you're doing something wrong.
>

It's sad to hear this, but unfortunately I would say that it was your
bad luck to work with bad designed APIs. Agreed, some projects get it
right from the 1st version, other are learning how to do it.

./alex
--
.w( the_mindstorm )p.

PS: probably we just have to agree to disagree :-). For me protected
is usefull and has been. Bad APIs is another topic and in some of the
companies I have worked for there were specific people for designing
the APIs for the frameworks used by hundred of other developers (I was
one of them :-) and frankly speaking, so far,  I haven't had such a
bad feedback as you describe).
76006c10b0773e69a6fcd70614ac258f?d=identicon&s=25 Joost Diepenmaat (Guest)
on 2006-06-01 00:40
(Received via mailing list)
On Thu, Jun 01, 2006 at 06:36:11AM +0900, Alexandru Popescu wrote:
> >My argument was that you then have to disallow people from implementing
> >their own classes based on your classes, because if they do, they still
> >can call the protected methods you just worked so hard to "protect".
> >
>
> But I haven't worked on protecting them against overridding, but
> against direct calls. Big difference.

Ofcourse.

> >My main point though, is that if you think you need protected methods you
> >should think really hard about wether other classes might find those
> >methods useful too (i.e. just make them public instead).
> >
>
> This is a matter of the API designer skills. However making everything
> public, for the sake that somebody may find one of the methods usefull
> is imo worse than having to evolve your initial API.

That's not what I meant. You can still make methods private. But if
methods
are useful enough to make protected / need to be accessible from
subclasses
or other instances, you should really stop and think if you _have_ to
deny
access from the rest of the code. If your classes are only going to be
used
in one project, knock yourself out - you can always change it later. But
if
you are writing reusable components... well, I think I've made my point
:-)

> bad luck to work with bad designed APIs. Agreed, some projects get it
> right from the 1st version, other are learning how to do it.

True enough.

Cheers,
Joost.
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles O Nutter (Guest)
on 2006-06-01 01:47
(Received via mailing list)
I believe the purpose of privatising methods is to avoid exposing
internal
implementation details that may change in future revisions of the code.
You
don't want people depending on methods you created internally to support
your public API, especially since those methods may be tied to
implementation details that should not be exposed.

Also, protected methods are not public..they are simply callable or
extensible within that branch of a class hierarchy. When a class extends
your base, it implicitly accepts responsibility for fulfilling the
contract
of your public API. If it chooses to use your protected methods, or even
expose them, it may do so at its own peril. Your base implementation
could
change in the future rendering that class nonfunctional and in violation
of
the base class's explicit contract. However, protected methods have the
option of being overridden; the extending class can (and often should)
provide its own internalized version of a protected method and have the
parent's methods then behave according to that new implementation.

The reason for protected versus private is this:

- protected methods define behavior that could logically differ between
classes in a hierarchy, but should generally not be exposed for direct
calls
to clients of the classes in that hierarchy. These are class-specific
methods that alter behavior between parent and child, allowing child
classes
to literally "extend" the behavior of the parent by providing a new
implementation without altering the public API.
- private methods are dependent enough on your specific implementation
or
localizable enough to a single level in the class hierarchy that they
should
not be exposed or overridden in any way. The behavior of a class or its
public API may be wholely dependent on that one implementation of an
algorithm, and child classes should not be allowed to replace it. By the
same token, that algorithm may have to change or go away in the future,
and
clients of the class or its subclasses should not call it directly.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-06-01 16:03
(Received via mailing list)
Alexandru Popescu wrote:
> At least in Java these modifiers are quite usefull: a protected method
> is one that offers extensibility/polymorphic behavior for hierarchies,
> without exposing it as public API. So the behavior may vary according
> to the implementation, and the exposed API/public methods are a
> completely different thing.

But Java != Ruby. In ruby, even private methods can be called from
instance methods of a subclass.

irb(main):001:0> class A; private; def foo; end; end
=> nil
irb(main):002:0> class B<A; def bar; foo; end; end
=> nil
irb(main):003:0> B.new.foo
NoMethodError: private method `foo' called for #<B:0xb7b36834>
        from (irb):3
irb(main):004:0> B.new.bar
=> nil

Protected is different from what you expect:

class A
  protected
#  private
  def foo
    puts "foo!"
  end

  public
  def call_foo_on_dup
    dup.foo
  end
end

A.new.call_foo_on_dup # ==> foo!

Now try it with private...
10d4acbfdaccb4eee687a428ca00a5d8?d=identicon&s=25 Jim Weirich (weirich)
on 2006-06-01 16:44
Alexandru Popescu wrote:
> At least in Java these modifiers are quite usefull: a protected method
> is one that offers extensibility/polymorphic behavior for hierarchies,
> without exposing it as public API. So the behavior may vary according
> to the implementation, and the exposed API/public methods are a
> completely different thing.

Keep in mind that Ruby protected and private have slightly different
meanings than in Java.  Private protection in Ruby is instance based.
That means that private methods are callable only within the object
instance, but (unlike Java) that instance need not be a direct instance
of the class.

Ruby protected seems to be pretty close to the Java concept of
protected, AFAICT (minus the package exposure in Java).  However, I
almost never use Ruby protected so I am probably missing some
subtleties.

-- Jim Weirich
30d4d2ca7684b3413d44d63742a3b285?d=identicon&s=25 Travis Detert (Guest)
on 2006-06-01 17:54
(Received via mailing list)
Sorry to send to the whole group, but I subscribed ages ago, and I've
completely forgotten where to unsubscribe from the list!
Thanks!
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 Ryan Leavengood (Guest)
on 2006-06-01 17:58
(Received via mailing list)
Seen in the headers of EVERY message to ruby-talk:

List-Unsubscribe: <mailto:ruby-talk-ctl@ruby-lang.org?body=unsubscribe>

Ryan
5c4e57ad9f066e56297a60b4a1daa1d3?d=identicon&s=25 Alexandru Popescu (Guest)
on 2006-06-01 18:01
(Received via mailing list)
Thanks Joel and Jim. I was aware that there are differences between
Ruby private/protected and Java private/protected, that's the reason
why I have said it load: "at least in Java these modifiers....". I
know how these are working for Java and I was commenting about their
usability. Indeed, considering that I am on the Ruby ML, I should have
probably prefix my messages with a little offtopic, so I apologize for
this.

BR,

./alex
--
.w( the_mindstorm )p.
Ff63c03fd68754adbadd2c6314646bef?d=identicon&s=25 Bill Guindon (agorilla)
on 2006-06-01 18:01
(Received via mailing list)
On 6/1/06, Travis Detert <travis@gsdesign.com> wrote:
> Sorry to send to the whole group, but I subscribed ages ago, and I've
> completely forgotten where to unsubscribe from the list!
> Thanks!

List-Unsubscribe: <mailto:ruby-talk-ctl@ruby-lang.org?body=unsubscribe>
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-06-03 14:04
(Received via mailing list)
2006/6/1, Joost Diepenmaat <joost@zeekat.nl>:
> That's not what I meant. You can still make methods private. But if methods
> are useful enough to make protected / need to be accessible from subclasses
> or other instances, you should really stop and think if you _have_ to deny
> access from the rest of the code. If your classes are only going to be used
> in one project, knock yourself out - you can always change it later. But if
> you are writing reusable components... well, I think I've made my point :-)

Note though that it's usually harder to remove functionality than to
add it, i.e. it's better to start with the more restricted version
(protected) and make methods public later if you see the need for
this. Nevertheless all sorts of problems arise if library code that is
inherited from is changed (e.g. if you make a protected method public
sub classes will break in Java because you cannot reduce visibility in
an overridden method).

An idiom I use from time to time makes explicit use of "protected": I
have an abstract base class that implements algorithms that rely on
specific parts implemented in sub classes; often these "parts" are
just getters that return a piece of data - but it can be more complex
of course. These things do not belong into the full light of public
because they are not the methods intended for primary use.  But I do
grant you that they must be viewed as part of the public interface
because they can cause dependencies - something which cannot happen
with private methods in Java.

Inheritance is an interesting but also complex field and difficult to
get right.

You said earlier: "I cann't think of any language that allows you to
do that."  Off the top of my head Eiffel is one of the languages that
does this. Bertrand Meyer thinks that implementation inheritance is as
good as interface inheritance and that's why sub classes can
completely change the public interface of their base classes.  Of
course then there is no longer an "is a" relationship and you cannot
use sub class instances where base class instances were allowed.  Btw,
even if you don't agree with all of his positions "Object-oriented
Software Construction" is nevertheless an interesting and valuable
read.

Kind regards

robert
This topic is locked and can not be replied to.