Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Eric Taylor
Hello Forum,

I'm aware that the "private" category and "protocols" are merely a way
to signal formal suggestions.  But is it possible to configure Code
Mentor to identify out-of-context calls to private methods, and to
identify unimplemented protocol methods in a class, perhaps give these
putative suggestions a little more significance?

Cheers,

Eric


Reply | Threaded
Open this post in threaded view
|

Re: Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Chris Uppal-3
Eric,

> [...] is it possible to configure Code
> Mentor to identify out-of-context calls to private methods,

What algorithm would you use to identify the context ?   IMO the meaning of
"private" is "I haven't published this -- you cannot rely on its meaning or
even existence in future releases".  A Java-like algorithm (called from a
different class) would (again, IMO) be completely inappropriate.


> and to
> identify unimplemented protocol methods in a class, perhaps give these
> putative suggestions a little more significance?

Doesn't the D6 protocol system do that for you already ?  I haven't played with
protocols in D6 yet, but in D5 (and earlier) the system maintained the
invariant that if protocol X required method #y, then every class which
implemented X has or inherits #y.  If you try to break the invariant then it
gives you the choice of removing the method from the protocol or removing the
protocol from the class.  So there can't /be/ any unimplemented methods.  Has
D6 changed ?  If so then it seems a very odd step, and I'd hope it's not by
design.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Eric Taylor
Hello Chris,

>What algorithm would you use to identify the context?

It would be difficult for me to say since I don't know how Code Mentor is
designed.  But I could conjecture.  Consider the class called OrderedCollection.
 Further, let's say the class has a method called #somePrivateOperation which
has been placed in the "private" category.  All that would be necessary,
fundamentally, is to detect message sends of #somePrivateOperation to other
than self (in the context of OrderedCollection).

Two issues arise that must addressed: a) the case where a class is a client
of itself; and b) the case where #somePrivateOperation is called from a descendant
class.  I haven't explored the former yet in Smalltalk.  In Eiffel, when
a class is a client of itself, the client usage is treated as if it were
a nonclient usage.  This means that all secret features of the class are
available to the client.  This is a design feature that permits recursive
inheritance, as in the case of the data structure TREE.  I haven't explored
the latter case above yet, either.  In Eiffel, secret features (analogous
to private methods in Smalltalk) are not available to descendants or clients,
except in the case I gave above.

>Doesn't the D6 protocol system do that [enforce protocols] for you already?

I guess this is the question I, myself, am asking.  The online help states
the following:

"Method protocols are the Smalltalk equivalent of Java (TM) interfaces. A
protocol consists of a series of message selectors that must be implemented
by a class if it is to conform to that protocol. In Smalltalk, protocols
are advisory only and not enforced."

How would you interpret this statement vis-a-vis your expectations of protocol-handling
in D6, as you outlined in your post?  I do like what you said about D5, and
I hope it applies to D6 as well.  I'll try to find some time to play around
with protocols this evening.

Cheers,

Eric


> Eric,
>
>> [...] is it possible to configure Code
>> Mentor to identify out-of-context calls to private methods,
> What algorithm would you use to identify the context ?   IMO the
> meaning of "private" is "I haven't published this -- you cannot rely
> on its meaning or even existence in future releases".  A Java-like
> algorithm (called from a different class) would (again, IMO) be
> completely inappropriate.
>
>> and to
>> identify unimplemented protocol methods in a class, perhaps give
>> these
>> putative suggestions a little more significance?
> Doesn't the D6 protocol system do that for you already ?  I haven't
> played with protocols in D6 yet, but in D5 (and earlier) the system
> maintained the invariant that if protocol X required method #y, then
> every class which implemented X has or inherits #y.  If you try to
> break the invariant then it gives you the choice of removing the
> method from the protocol or removing the protocol from the class.  So
> there can't /be/ any unimplemented methods.  Has D6 changed ?  If so
> then it seems a very odd step, and I'd hope it's not by design.
>
> -- chris
>


Reply | Threaded
Open this post in threaded view
|

Re: Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Chris Uppal-3
Eric,

[me:]
> > Doesn't the D6 protocol system do that [enforce protocols] for you
> > already?
>
> I guess this is the question I, myself, am asking.

Why not try it and see ?

If D6 doesn't behave how I've described D5 doing, then either that's a bug or a
serious (IMO) retrograde step.  In either case it would be something to take up
with OA (who may or may not be reading this thread already).

=======

> > What algorithm would you use to identify the context?
>
> It would be difficult for me to say since I don't know how Code Mentor is
> designed.

No, I meant: what's the functional spec ?  Not, how is it to be implemented
(I've never looked at Code Mentor at all, so I have no ideas about
implementation)


> All that would be necessary,
> fundamentally, is to detect message sends of #somePrivateOperation to
> other
> than self (in the context of OrderedCollection).

Yes, that's my question -- how do you define "context" ;-)


> Two issues arise that must addressed: a) the case where a class is a
> client
> of itself; and b) the case where #somePrivateOperation is called from a
> descendant class.

I really think that you are going about this in the wrong way.  You are, I
suspect, over-generalising from Eiffel, and being (mis)lead into thinking that
a superficially similar concept in Smalltalk is, in fact, only superficially
different.

I don't know Eiffel (I read /the/ book many, many, years ago, and that's it ;-)
so I'll talk in terms of Java when I need concrete examples.

In Smalltalk, as you know, the private/non-private, distinction is advisory.
You might say that it's part of the method's documentation rather than its
implementation.  That is a very important difference from how Java works, and
its a much bigger difference than it looks (especially if you think of it as
"Smalltalk has a sort of private/non-private distinction but it's not enforced
by the compiler or runtime").  The Smalltalk notion is /not/ an approximation
to the Java notion -- if anything it's the other way around.

The private flag is a communication from one programmer to another.  (Not a
communication from a programmer to the compiler, which another programmer might
find interesting too -- as is the case for things like choice of variable
names.)  But what is it /saying/ ?   Actually, there are a number of
possibilities here, but the one I favour (and which subsumes many of the other
interpretations), is that it's indicating whether or not a method has been
/published/ (my terminology).  By "published" I mean that the author of the
code has committed to maintaining that method, with its current meaning and
mode of operation, in future releases of the code.  A private method, OTOH, may
be changed without notice, comment, explanation, and certainly without apology,
in even the most minor subsequent release.  It means "no promises".  It
/doesn't/ mean "you mustn't use this method", it's just flagging that if you
/do/ then you are to some degree on your own.

Notice how that doesn't follow class boundaries particularly.  E.g. I might
have a method on one of my classes which is private, but which is actually
called from other, unrelated, classes.  In fact this happens a /lot/.  (One
example which might surprise you: it's pretty common for object initialisation
methods to be private, but yet invoked by the class's factory methods -- yet
they belong to a different object of a completely different class!)   Another
example, if I add a loose method to one of the core classes, that doesn't
suddenly have the "right" to invoke private methods of that class.  It's just
as much breaking encapsulation if I do it from a method attached to that
class, as if I did it from anywhere else.

In point of fact, the OA codebase uses "private" in a couple of other senses
too.  Broadly speaking: "here be monsters".  It could mean: "you'd better know
what you're doing if you call this yourself" (such as some of the methods on
MemoryManager, SessionManager, and InputManager).  Or it could mean "you
probably don't need to know about this", which is the message I think OA intend
to convey by making most of the Win32 underpinnings of class View private.  It
isn't that you shouldn't use them (you /have/ to do so if you want to use Win32
features that are not exposed more conveniently), but that you don't need to
look at them to understand how Views are supposed to be used.

Anyway, and taking only the "private" == "not published" interpretation, you'll
see that the message is not at all like Java's "private".  It's rather more
like Java's "default access", aka "package-private", but even that is a dull
tool for attempting to convey the distinction.  (The fact that access control
is enforced by the compiler/runtime, also changes the meaning from "you would
be well-advised not to use this without thought" to "there is absolutely no way
that you should ever use this" -- a fairly considerable change of emphasis ;-)

It may well be that Eiffel has a more finely tuned way to express what is
"published" and what isn't than Java (it seems to fit very /nicely/ with the
general notion of contracts).  Or even a more finely expressed division that
just a binary choice between "published" and "private" (the question is
"published to whom?").  I don't know.  You may be aiming for something more
expressive than the distinction I'm making, but I don't think you should be
aiming for something /less/ expressive.

That the difficult thing here is finding a mechanical test which corresponded
reasonably closely to "is published or is in same <context> as the calling
method", and detecting self sends doesn't seem (to me) to come close to that.
One rough approximation would be to check if any selector named only methods
which were neither public, nor in the same package as the caller (remembering
that methods need not be in the same package as their class).  If not then that
reference could be flagged as iffy.  If you want to try to implement that, then
all the information is available in the image (via public methods too!).  But
note that some of the needed operations are fairly slow; you might be forced to
build some sort of database in order to achieve acceptable interactive
performance.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Eric Taylor
Hello Chris,

>Why not try it and see?

Indeed :).

Concerning the semantics of "private" in Smalltalk versus those of "secret"
in Eiffel (or Java, for that matter), you make a number of valid points.
   For me, the easiest way to pick up a new language is to identify the differential,
which is usually much smaller than the full specification.  As I learn Smalltalk,
I use Eiffel as a frame a reference (but not as a basis for comparison),
much in the same way you call upon Java.  There are so many similarities
between Eiffel and Smalltalk, that it has actually been instructive to do
that.

>I really think that you are going about this in the wrong way.  You are,
I suspect, over-generalising from Eiffel, and being (mis)lead into thinking
>that a superficially similar concept in Smalltalk is, in fact, only superficially
different.

Probably, on both counts.  I have to remind myself that Smalltalk came first.
 I've read just about everything that Bertrand Meyer wrote, or co-wrote,
and one could say that Smalltalk's implementation of "private" was the seed
for Eiffel's implementation of "secret."  Mr. Meyer never actually claimed
this, to my knowledge, but I feel it's there, between the lines.  You offer
an excellent example in the form of a Class Factory pattern as to why an
inviolable "private" would actually thwart the implementation of such a pattern.
 Parenthetically, one could argue that this is the seed that gave rise to
Eiffel's treatment of classes as clients of themselves, and even the introduction
of the "friend" operator into the C++ language.  Smalltalk seems to overcome
this side effect of encapsulation by simply making "private" advisory.

In re-reading your reply just now, between paragraphs, something struck me:
Smalltalk affords such a high level of abstraction, allows the application
to execute so remotely from the platform on which it is executing, that I
suppose constructs and semantics different from those of compiled languages
are necessary.  As you say, one is free to use a private method if necessary.
 By making "private" advisory, one can take the liberty, if necessary, of
penetrating deep into the framework to manipulate the underlying machine
at that level.  The caution keeps the monsters at bay, to extend your metaphor,
but allows one to engage them if necessary.

>It may well be that Eiffel has a more finely tuned way to express what is
"published" and what isn't than Java...

It does.  Given Class ABC, class features can be exported to {NONE}, making
them secret (private in C++); {ANY}, making them public (public in C++),
which is not necessary to declare since it is the default; {ABC}, making
the features available to the class itself and its descendents (protected
in C++); and, most importantly, features can be selectively exported to a
specific list of classes {XYZ, MNO, EFG}, similar to "friend" in C++ but
without all of the problems associated with such coupling.  I can see both
the power--and danger--of an advisory "private" in Smalltalk.  But then danger
usually comes with power ;).

On that note, I do still feel that the Code Mentor should advise of certain
types of usage of private calls, if for no other reason than to reaffirm
the programmer's intention to penetrate deeper into a class.  Such a mofication
would be an excellent exercise in understanding how the development environment
is put together.

I'm very excited about this thing you call Smalltalk!  I know I've said that
before in other posts, but it's been so long since I've been excited about
anything in programming.  I'm about a year and a half into The Smalltalk
Report and about halfway into Ted Bracht's book...there's so much to learn.

By the way, thank you for putting me on to the TotallyObjects news server.
 I switched over, and everything is running much more smoothly now.

Cheers,

Eric




> Eric,
>
> [me:]
>
>>> Doesn't the D6 protocol system do that [enforce protocols] for you
>>> already?
>>>
>> I guess this is the question I, myself, am asking.
>>
> Why not try it and see ?
>
> If D6 doesn't behave how I've described D5 doing, then either that's a
> bug or a serious (IMO) retrograde step.  In either case it would be
> something to take up with OA (who may or may not be reading this
> thread already).
>
> =======
>
>>> What algorithm would you use to identify the context?
>>>
>> It would be difficult for me to say since I don't know how Code
>> Mentor is designed.
>>
> No, I meant: what's the functional spec ?  Not, how is it to be
> implemented (I've never looked at Code Mentor at all, so I have no
> ideas about implementation)
>
>> All that would be necessary,
>> fundamentally, is to detect message sends of #somePrivateOperation to
>> other
>> than self (in the context of OrderedCollection).
> Yes, that's my question -- how do you define "context" ;-)
>
>> Two issues arise that must addressed: a) the case where a class is a
>> client
>> of itself; and b) the case where #somePrivateOperation is called from
>> a
>> descendant class.
> I really think that you are going about this in the wrong way.  You
> are, I suspect, over-generalising from Eiffel, and being (mis)lead
> into thinking that a superficially similar concept in Smalltalk is, in
> fact, only superficially different.
>
> I don't know Eiffel (I read /the/ book many, many, years ago, and
> that's it ;-) so I'll talk in terms of Java when I need concrete
> examples.
>
> In Smalltalk, as you know, the private/non-private, distinction is
> advisory. You might say that it's part of the method's documentation
> rather than its implementation.  That is a very important difference
> from how Java works, and its a much bigger difference than it looks
> (especially if you think of it as "Smalltalk has a sort of
> private/non-private distinction but it's not enforced by the compiler
> or runtime").  The Smalltalk notion is /not/ an approximation to the
> Java notion -- if anything it's the other way around.
>
> The private flag is a communication from one programmer to another.
> (Not a communication from a programmer to the compiler, which another
> programmer might find interesting too -- as is the case for things
> like choice of variable names.)  But what is it /saying/ ?   Actually,
> there are a number of possibilities here, but the one I favour (and
> which subsumes many of the other interpretations), is that it's
> indicating whether or not a method has been /published/ (my
> terminology).  By "published" I mean that the author of the code has
> committed to maintaining that method, with its current meaning and
> mode of operation, in future releases of the code.  A private method,
> OTOH, may be changed without notice, comment, explanation, and
> certainly without apology, in even the most minor subsequent release.
> It means "no promises".  It /doesn't/ mean "you mustn't use this
> method", it's just flagging that if you /do/ then you are to some
> degree on your own.
>
> Notice how that doesn't follow class boundaries particularly.  E.g. I
> might have a method on one of my classes which is private, but which
> is actually called from other, unrelated, classes.  In fact this
> happens a /lot/.  (One example which might surprise you: it's pretty
> common for object initialisation methods to be private, but yet
> invoked by the class's factory methods -- yet they belong to a
> different object of a completely different class!)   Another example,
> if I add a loose method to one of the core classes, that doesn't
> suddenly have the "right" to invoke private methods of that class.
> It's just as much breaking encapsulation if I do it from a method
> attached to that class, as if I did it from anywhere else.
>
> In point of fact, the OA codebase uses "private" in a couple of other
> senses too.  Broadly speaking: "here be monsters".  It could mean:
> "you'd better know what you're doing if you call this yourself" (such
> as some of the methods on MemoryManager, SessionManager, and
> InputManager).  Or it could mean "you probably don't need to know
> about this", which is the message I think OA intend to convey by
> making most of the Win32 underpinnings of class View private.  It
> isn't that you shouldn't use them (you /have/ to do so if you want to
> use Win32 features that are not exposed more conveniently), but that
> you don't need to look at them to understand how Views are supposed to
> be used.
>
> Anyway, and taking only the "private" == "not published"
> interpretation, you'll see that the message is not at all like Java's
> "private".  It's rather more like Java's "default access", aka
> "package-private", but even that is a dull tool for attempting to
> convey the distinction.  (The fact that access control is enforced by
> the compiler/runtime, also changes the meaning from "you would be
> well-advised not to use this without thought" to "there is absolutely
> no way that you should ever use this" -- a fairly considerable change
> of emphasis ;-)
>
> It may well be that Eiffel has a more finely tuned way to express what
> is "published" and what isn't than Java (it seems to fit very /nicely/
> with the general notion of contracts).  Or even a more finely
> expressed division that just a binary choice between "published" and
> "private" (the question is "published to whom?").  I don't know.  You
> may be aiming for something more expressive than the distinction I'm
> making, but I don't think you should be aiming for something /less/
> expressive.
>
> That the difficult thing here is finding a mechanical test which
> corresponded reasonably closely to "is published or is in same
> <context> as the calling method", and detecting self sends doesn't
> seem (to me) to come close to that. One rough approximation would be
> to check if any selector named only methods which were neither public,
> nor in the same package as the caller (remembering that methods need
> not be in the same package as their class).  If not then that
> reference could be flagged as iffy.  If you want to try to implement
> that, then all the information is available in the image (via public
> methods too!).  But note that some of the needed operations are fairly
> slow; you might be forced to build some sort of database in order to
> achieve acceptable interactive performance.
>
> -- chris
>


Reply | Threaded
Open this post in threaded view
|

Re: Code Mentor: Identifying Access to Private Methods and Unimplemented Protocol Methods?

Chris Uppal-3
Eric,

> > Why not try it and see?
>
> Indeed :).

OK, new thread coming up...


> Smalltalk seems to overcome
> this side effect of encapsulation by simply making "private" advisory.

You might say that Smallalk adopts a human solution to a human problem, rather
trying to shoehorn a technical solution in.

But that's a bit pompous, so it'd probably better to leave it unsaid ;-)


> On that note, I do still feel that the Code Mentor should advise of
> certain
> types of usage of private calls, if for no other reason than to reaffirm
> the programmer's intention to penetrate deeper into a class.  Such a
> mofication would be an excellent exercise in understanding how the
> development environment
> is put together.

Sound like a valuable addition.  Good luck !

    -- chris