I understand how to do everything in C, everything is simple and clear.
Funny that you'd say that because I have the exact same conclusion when working with c in that I find it much more simple and clear using Pascal
how to do this in Pascal gives me a whirlwind of confusion about the concept of language/structure/interaction.
If you are new to Pascal then this 'feeling' is going to stay there for a while. It does become better, I promise.
you can sketch your solution with the third file?
Yeah, sure.
Project file:
program prj1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes, SysUtils, CustApp, { ignore this unit to be a fpc only application --> LazFileUtils} uGlobals, // <-- new 3th unit
parser;
type
// Types in Pascal are prefixes with a T. That is not a rule but common
// practice to not confuse variables/constants with types.
// Everyone I know that programs in Pascal uses this practice so not doing
// so is able to confuse people.
// I also asjusted the source-code to use proper indentation, which becomes
// very important when writing nested loops.
TMyApplication = class(TCustomApplication)
protected
procedure DoRun; override;
public
constructor Create(TheOwner : TComponent); override;
destructor Destroy; override;
end;
// this is now declared inside unit uGlobals
//var
// Application : app;
procedure TMyApplication.DoRun;
begin
// ignore this line --> parser.init(Application);
parser.proc;
Terminate;
end;
constructor TMyApplication.Create(TheOwner : TComponent);
begin
inherited Create(TheOwner);
StopOnException := True;
end;
destructor TMyApplication.Destroy;
begin
inherited Destroy;
end;
// Do not declare this variable in your project file anymore but instead use
// a 3th unit which I named uGlobals
// var Application : app;
{$R *.res}
begin
Application := TMyApplication.Create(nil);
Application.Title := 'app';
Application.Run;
Application.Free;
end.
parser file:
unit parser;
{$mode objfpc}{$H+} // place this here and not inside the interface section
interface
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes, SysUtils, CustApp;
// not necessary anymore --> procedure init(p:TCustomApplication);
procedure proc;
implementation
uses
uGlobals; // <-- add 3th unit that contains global variables which can be used by all of your units in order to access global variables.
// Note necessary anymore, use application from uGLobals
// var
// app:TCustomApplication;
//procedure init(p:TCustomApplication);
//begin
//app := p;
//end;
procedure proc;
begin
if(appplication.hasOption('h', 'help')) then // uses CustApp
writeln('yes')
else
writeln('no');
end;
initialization
finalization
end.
3th unit, that I named uGlobals
unit uGlobals;
interface
uses
CustApp;
var
Application: TCustomApplication;
implementation
end.
Is that more clear ?
It is a common practice that is used to 'share' common declarations between several different units on your project. This becomes more evident when using Lazarus and have many visual forms.
addition:
by “analogy with C” - I added not an object, but a pointer to an object (for a module - the pointer will be an internal variable,
which fits well with the correct concept of data hiding)
imho
Yes, but you basically do the same by passing TCustomApplication to your init routine (in practice that is a pointer).
edit: I pasted the wrong parser unit, corrected.