>> So to me, any with clauses that apply to only one subprogram in the body
>> are very suspect, and almost always indicate a design flaw.
Richard Riehle replied:
> The expression, "almost always" might be correct. Unfortunately, some
> will interpret this as a "Thou shalt not have context clauses for a
> subunit." I am fairly sure you would not want to suggest something
> that extreme.
If someone had a package with three subunits that had withs for some
other package, I wouldn't flinch. But what I see, and it is almost always
a design flaw, is that the designer of the package thought he needed the
second package for "only one" operation. In real systems it is very rare
that you want to start something and not stop it, link something on a list,
but never unlink it, etc. If someone uses a subset of the provided
interface, no surprise. But if they assert that there is only one
operation on that abstraction needed in this context, I get very
suspicious. That is much more what I am driving at than the fairly typical
case where you have a small subset the operations in a package that use
I/O or transcendental math operations or what have you.
Go take a look at some typical packages or class libraries or what have
you. There are some where you want to make two sets of calls. For example
in a semaphore package you have calls to P and calls to V (or if you
prefer, Seize and Release, or Get and Free). Another group of packages
typically have three sets of calls, and some have four. But if an
abstraction is expecting to be called in only one way, it should be a
subroutine, not a package or class.
Now imagine you are reading some code and find a with of the semaphore
package. Closer inspection shows that this routine only calls Seize and
never release. You go confront the programmer, and he tells you that yes,
his package reserves the file handles or whatever, while Joe's package
releases them! That is the heresy that I, from experience, associate with
withs on subunits. They always seem to show up in situations where the
natural organization has been hacked up and the pieces scattered. It isn't
that they can't be used in a reasonable fashion, its that the mental push
to use them comes from decompositions that are flat out wrong.
On the other hand, I've "corrected" the problem when I detected it in
my code by adding the missing interfaces, but providing a body that raises
program error. I always end up writing the missing code, often before
anything gets compiled. For example, a linked list abstraction where I
thought I'd never need to unlink things. Turned out that the application
eventually needed the "extra" interfaces, but I'd already had to add them
to do any sort of reasonable unit testing.
Robert I. Eachus
function Message (Text: in Clever_Ideas) return Better_Ideas is...