[Cuis-dev] Why can't you send to super on private (pvt*) methods?

Phil B pbpublist at gmail.com
Tue Jun 11 17:02:25 PDT 2019


Andres,

(In your first message you suggested asking why the functionality I'm
complaining about was designed the way it is.  Please re-read my original
post in this thread: that's exactly what I was asking.  Barring an explicit
rationale, my belief is that the current behavior was likely an oversight
as opposed to an explicit design decision.  Unless someone recalls the
discussion from back then or comes across some explicit documentation, we
may never know for sure which is the case.)

On Tue, Jun 11, 2019 at 6:50 PM Andres Valloud via Cuis-dev <
cuis-dev at lists.cuis.st> wrote:

> Take the following method.
>
> Collection>>pvtDoStuff
>         "So now people can't do super"
>
>
> What prevents anybody from doing this?
>
> Array>>indirectPvtDoStuffAnyway
>
>         self pvtDoStuff.  "so now it's a self send"
>         self myPvtDoStuff
>
>
Nothing whatsoever.  It's also valid in the superclass to send
#pvtSubMethod that doesn't exist on super but does on the subclass and that
works too.  It's only the explicit 'super pvtDoStuff' case (that I've run
into so far) that won't work within the class hierarchy the way I'd
expect.[1]  To me, it's an annoyance because if I really need to send super
on it (i.e. a subclass needs to extend, but not replace, the existing
functionality), then I'm forced to rename it to something like #private* to
do so currently.

I'm not under the illusion that this mechanism provides any iron clad
guarantee that a given method can't/won't be called externally, only that
it provides a minimal compiler assist that will slow you down to make an
explicit decision when you want to do so.  Human beings behaving the way
they do, I don't have any illusions that *any* software mechanism put in
place would work to truly enforce a concept like privacy.  That's fine...
it's not what I care about.  In my mind, all a mechanism like #pvt* does is
signal that 'this method isn't meant to be called by you, it's an internal
implementation detail' and if you decide you really need it to be exposed
publicly, make an explicit decision to do so in the form of renaming the
method.  So the compiler error is more a speed bump and one can eliminate
said speed bump if/as needed.  The problem I see with the super case is
that it's an illogical speed bump since as you point out above, there's no
other attempt to prevent sending #pvt* up/down the class hierarchy.


> There is no such thing as "removing any possible misinterpretation".
> The more one pushes in this direction, the more binary the perspective
> (either "super bad" or "acceptable"), and the outcome is that one's
> particular designs become limited by these general restrictions.
>

All I am suggesting is that an explicit prefix, as opposed to using method
category, would more clearly communicate to developers that those methods
were not intended to be called outside the class hierarchy.  A problem I've
run into numerous times with code that uses say the 'private' category for
a given method is that there may be super/subclasses that either forget to
categorize it or worse put it in a different category... then what is
someone downstream to make of whether or not they should use that method?


> In fact, this approach might end up inducing ironic results.  Since the
> programmer will yield the decision of which message to send to the
> system (!), that's yet another instance of enabling not thinking things
> through or understanding what's going on.  And you know the result of
> that: more bad code.
>

The alternative is relying on inconsistent usage of categories, depending
on class/method comments that at best are incomplete etc.  I don't see it
as yielding to the system as much as the judgement of whoever wrote the
code you are using.  And in the case of a useful method being made private,
a complaint is a useful signal to the developer/maintainer of a piece of
code that they need to find some way (either by directly renaming the
method in question or by providing an alternative means) of providing the
desired functionality externally.

Thanks,
Phil

[1] As I've alluded to in my responses to Juan, it also doesn't work going
from instance->class or class->instance side.  To me, that makes sense:
it's (mostly) consistent with how variable visibility works.


> On 6/11/19 10:43, Phil B via Cuis-dev wrote:
> > Ah, then count me as a firm 'yes' vote!  I've been in favor of that
> > forever as I agree making things explicitly pvt* removes any possible
> > misinterpretation.  The only problem is that many (most?) the senders of
> > those set* methods tend to come from class-side so pvt* visibility would
> > have to extend there as well for this to work. (What I tend to do
> > currently for those cases in my code currently is use a private* prefix.)
> >
> > On Tue, Jun 11, 2019 at 1:28 PM Juan Vuletich <juan at jvuletich.org
> > <mailto:juan at jvuletich.org>> wrote:
> >
> >     __
> >     On 6/10/2019 8:15 PM, Phil B wrote:
> >>
> >>         Why do you think the #privateSetX:setY: looks silly?  I think
> >>         it's a decent placeholder that I read as saying 'we really
> >>         want this to be immutable and are indicating this as private
> >>         to reflect that fact until we can actually make it immutable
> >>         via the VM'
> >>
> >
> >     Because the comment begs you not to call it. If we just add the pvt
> >     prefix, then it is way more robust. You need to add a new method to
> >     set the ivars, and clearly you are on your own then.
> >
> >>
> >>     Private categories are good for getting methods out of the way in
> >>     the main browser but I'm not wild about them beyond that.  The
> >>     main issue I have with private categories is that they are so easy
> >>     to overlook in the browsers.  For example, if you're in the
> >>     message finder and you do a search on 'set', the fact that it
> >>     shows up as private* makes it very clear that it's not a method
> >>     you should be using generally.  If the private prefix were
> >>     removed, you'd have to be sure to select an implementor in the
> >>     right pane (and hope that they are consistently categorized) and
> >>     then be sure to look for the category buried in the method
> >>     annotation below (which might be 'private' or 'private -
> >>     someSubCategory' etc)... ugh!  Or if you see a raw selector (i.e.
> >>     #setX:setY:) in code now you have to do the above as opposed to
> >>     just looking at the selector name.
> >>
> >>     That said, if it really bugs you or others, I will live without
> >>     the prefix.  But I do find it helpful.
> >>
> >>     Thanks,
> >>     Phil
> >
> >     I'm suggesting the opposite! To start adding the pvt prefix to
> >     methods we intend to be private (i.e. those already in a 'private*'
> >     category).
> >
> >     Cheers,
> >
> >     --
> >     Juan Vuletich
> >     www.cuis-smalltalk.org  <http://www.cuis-smalltalk.org>
> >     https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev
> >     https://github.com/jvuletich
> >     https://www.linkedin.com/in/juan-vuletich-75611b3
> >     @JuanVuletich
> >
> >
> --
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20190611/cc3e6b58/attachment-0001.htm>


More information about the Cuis-dev mailing list