According to Hans Ecke:
1.) heredity and virtuall routines for units (yes, I mean objects!) [...] So what I would like to see would be:
/////////////////////////////////////////////////
unit graph_fast(graph);
If I understand this correctly, you mean that your unit `graph_fast' shall export everything that `graph' does but override `putpixel' and `line' with new implementations.
Well, this is just overloading of procedures, nothing "virtual".
(* Something like "virtual procedures" in units would be the following: Program X uses unit A and calls a procedure `foo' in A. Unit B uses unit A too and overrides `foo'. "Virtual" means that program X - which does not use B directly - in fact calls `B.foo', not `A.foo'.
You do not really mean this, do you? { Well ... I just discovered: you *do* mean this. (See below.) } *)
The mechanism you suggest requires qualified identifiers, so procedures with the same name can coexist in different units in the same project. This is planned for gpc-2.2.
Up to then, you can get the intended effect of `Unit graph_fast ( Graph )' using the following kludge:
Unit Graph_Fast;
uses Graph;
Procedure Fast_PutPixel ( ... ); (* Implemented below *); Procedure Fast_Line ( ... ); (* Implemented below *);
Procedure Bar ( ... ); External; (* "Inherits" from `Graph' *)
...
Implementation
(* Implement `Fast_PutPixel' and `Fast_Line' *)
end.
Once qualified identifiers will exist, you can get rid of the `Fast_' name prefix.
Having said that, it might be a good idea to implement your idea "Unit foo ( bar )" as a shortcut to produce the result sketched above. *Perhaps* in gpc-2.2.
procedure putpixel(x,y:integer); begin writeln(logfile,`Putpixel with parameters `,x,`,`,y); inherited putpixel(x,y); end;
Okay, now you want `Graph' (or `Fast_Graph') use your overridden `PutPixel' instead of its own `PutPixel'. This can only be done with pointers, like Frank pointed out. This *is* virtuality.
If you want to implement that, modify `Graph' such that `PutPixel' is a procedural variable:
Var PutPixel: Procedure ( ... );
Then you must, of course, initialize it (perhaps in `InitGraph'), i.e. manually write a "constructor" for your "object". I have done this in the past (BO4), and it works in a great way.
(* Since our `Graph' unit is *not* a port from Borland Pascal but was rewritten from scratch and comes with full source (C and Pascal), it is *no problem* to modify it this way. :*)
To override the "virtual procedure" `PutPixel', your `Fast_Graph' unit needs to do nothing but to assign a new value to that `Putpixel' variable. You can do it with the current version of GPC (or with BP for that matter).
Maybe one could consider also Multi-heredity (is this a understandable word?)
It is, but the correct word is "multi-inheritance".
With units, this would be no real problem - provided that we are not talking about virtual procedures. When it comes to virtual procedures, the same problems arise for units as for objects.
Summary: The feature you are asking for does not (yet?) exist, but you can work around them relatively easily.
But: If you want to have the features of objects for your library, why don't your libraries export objects instead of "ordinary" procedures? I am currently writing a library (BO5) which does it that way: All input/output is done through objects having virtual methods, so you can easily replace `PutPixel' with a different routine - and the whole library will work with this new procedure. Borland's "Graph" (BGI) API is not the ultimate way to implement a graphics library. I suggest to write the library using objects and to provide some ordinary procedures that use the objects as an interface for compatibility.
2.) Making Libraries from units I don't know if this task allready done.
It is - for the objects. You can put them together in an `.a' file. (See the documentation of `ar' and `ranlib'.)
For the interfaces (`.gpi' files) this is not possible at the moment. Your "parent unit" mechanism would provide an easy way to "concat" `.gpi' files, so the calling program only needs to use *one* unit and gets the functionality of all of them. Not a bad idea.
Such a
Unit BO5 ( Tools, Objects, Events, Displays, whatever );
(* "BO5" is the name of my planned ultimative library; you can substitute "EFLIB" if you prefer something already existing. ;*)
Interface
Implementation
end.
would produce one large `.gpi' file such that "uses BO5" would give all the functionality of `Tools', `Objects', etc. to the program and tell the linker to link all the files `tools.o', `objects.o', etc.
(* Perhaps Borland's syntax "Library BO5" instead of "Unit BO5" would be a reasonable extension to directly produce `libbo5.a', i.e. automatically invoke `ar' and `ranlib'? *)
Greetings,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [971005] maintainer GNU Pascal [971001] - http://home.pages.de/~gnu-pascal/ [971005]