Re: Private headers in GSMake frameworks?

From:

Nicola Pero

Subject:

Re: Private headers in GSMake frameworks?

Date:

Sat, 30 Oct 2004 20:50:03 +0100 (BST)

For example, say your framework is called 'Framework'. You can put your
public headers in
Framework/Header.h
and your private/protected ones in
Framework/Private/Header.h
Then it's obvious that
#include <Framework/Private/Header.h>
is using private/protected headers of the framework, and
#include <Framework/Header.h>
is using a public header.

Yes, there are many workarounds for this, not the least of which being
just doing away with the distinction and adding a comment to the top of
the header file saying it's private.
However, on MacOS X, you don't use a different #import statement to get
at a private header.
#import <Framework/Header.h>
will look in both places.

Ok. Thanks for the explanations!
... But the feature doesn't look nice to me. :-/
If I look at the source code of an application and I see
#import <Framework/Header1.h>
#import <Framework/Header2.h>
I won't be able to know what is public and what is private.

A couple of years after the software was written, nobody (not even the
original authors) will remember which header was private and which was
public. So when a new version of the framework comes out, you'll be
facing the question: which of your files depend on private headers /
features (and so needs review and updates) and which depend only on public
ones (and so are safe) ?

Whatever mechanism you're using for marking private headers, it should
make it easy to answer that question. Unfortunately what you're
describing doesn't help -- you won't be able to answer this question
looking at your code or using grep, you have to go through all files and
look at what you are including. Which could be hard if, as it normally
happens, you are actually including plenty of headers from a lot of
different frameworks. Do you really want to have to go around and check
all and each of the #import to see which included files and private and
which are public ? That doesn't sound clever to me.

Moreover, if it's free software, I might well be cutting&pasting from one
free software application into another free software app, and I might well
not be thinking much while I copy. People copy because they don't want to
think. So I just look for an application which is using Framework, and I
just copy a bunch of header includes of headers from Framework from that
app since I want to use Framework too. Consequence is I might easily end
up including private headers without knowing they are private, since they
are indistinguishable from the public ones in the way they are included.

Which, to me, sort of defeats the whole purpose of having 'private'
headers installed in a separate location ... you make them 'private' to
prevent developers from using them unless they really want to use private
headers.

So I personally think that self-explanatory includes like
#import <Framework/Private/Header1.h>
#import <Framework/Header2.h>

are enormously better than this Apple invisible private headers installed
in a different location but indistinguible in the source code from public
headers. I can't really see the point of that. If it's a private header,
what's wrong with having an #import which clearly communicates to someone
reading the code that you are including a private header (a very dangerous
and risky operation) ?

Including private headers should be something which you spot immediately
when you look at the source code, because if you are reviewing software
written by someone else which no longer works with the latest version of
whatever framework they're using, such private header includes/imports
probably are the first thing you want to check. So they should be easy to
find, not hidden and confused with the public imports.

If you really need this, presumably what we could have in gnustep-make for
source code compatibility, you could mark some headers as PRIVATE_HEADERS.
Normally, those would be installed in exactly the same location as the
normal headers (we don't want the PrivateHeaders directory in the usual
gnustep as it's yet an additional complication whose benefits are not
really convincing). On MacOSX with the Apple combo, they would be
installed in PrivateHeaders as Apple does. You would be able to import
all of them as #import <Framework/Header.h> on both Apple and GNU.

I don't like the feature so I'm not particularly excited at the idea
though, but if you find it useful, we could set it up in this way.

Anyway, thanks very much for the very clear and detailed explanations and
for taking the time of discussing this issue with me.