First cut, overload the Write/WriteLn procedures. A bit awkward, as it needs to be done for
each new type, and full qualification is needed to get the original Write/WriteLn.
// author: Mark W. Naylor
// file: recordwrite.pas
// date: 2018-Aug-12
program RecordWrite;
type
TPerson = record
FirstName: String;
LastName: String;
end;
procedure Write(Person: TPerson); overload;
begin
System.Write('My name is ' + Person.FirstName + ' ' + Person.LastName + '.');
end; {Write}
procedure WriteLn(Person: TPerson); overload;
begin
Write(Person);
System.WriteLn;
end; {WriteLn}
var
SpaceHero: TPerson;
begin
with SpaceHero do
begin
FirstName := 'Flash';
LastName := 'Gordon';
end; { with SpaceHero }
WriteLn(SpaceHero);
end. { RecordWrite }
What we really want to do is overload just once, but records aren't classes.
// author: Mark W. Naylor
// file: recordwrite.pas
// date: 2018-Aug-12
program RecordWrite;
type
TPerson = record
FirstName: String;
LastName: String;
function ToString(): String;
end;
function TPerson.ToString(): String;
begin
Result := 'My name is ' + FirstName + ' ' + LastName + '.';
end; {TPerson.ToSting}
// What we really want to do is overload Write and WriteLn just once.
procedure Write(Obj: TObject); overload;
begin
System.Write(Obj.ToString());
end; {Write}
procedure WriteLn(Obj: TObject); overload;
begin
Write(Obj);
System.WriteLn;
end; {WriteLn}
var
SpaceHero: TPerson;
begin
with SpaceHero do
begin
FirstName := 'Flash';
LastName := 'Gordon';
end; { with SpaceHero }
// Next line will cause compiler error. Unfortunately, records are not objects.
// WriteLn(SpaceHero);
(*
Full qualification needed to call original WriteLn. And, we need to directly call the ToString method.
*)
System.WriteLn(SpaceHero.ToString());
end. { RecordWrite }
Since the record already has methods, why not make it an actual class?
// author: Mark W. Naylor
// file: recordwrite.pas
// date: 2018-Aug-12
program RecordWrite;
uses
SysUtils;
type
// Better yet, maybe, upgrade from record to actual class.
TPerson = class
fFirstName: String;
fLastName: String;
function ToString(): String; override;
constructor Create(FirstName: String; LastName: String);
end;
function TPerson.ToString(): String;
begin
Result := 'My name is ' + fFirstName + ' ' + fLastName + '.';
end; {TPerson.ToSting}
constructor TPerson.Create(FirstName: String; LastName: String);
begin
fFirstName := FirstName;
fLastName := LastName;
end; {TPerson.Create}
// What we really want to do is overload Write and WriteLn just once.
procedure Write(Obj: TObject); overload;
begin
System.Write(Obj.ToString());
end; {Write}
procedure WriteLn(Obj: TObject); overload;
begin
Write(Obj);
System.WriteLn;
end; {WriteLn}
var
SpaceHero: TPerson;
begin
SpaceHero := TPerson.Create('Flash', 'Gordon');
WriteLn(SpaceHero);
FreeAndNil(SpaceHero);
end. { RecordWrite }
This allows us to do specialized output.
// author: Mark W. Naylor
// file: recordwrite.pas
// date: 2018-Aug-12
program RecordWrite;
uses
SysUtils;
type
// Better yet, maybe, upgrade from record to actual class.
TPerson = class
public
function ToString(): String; override;
constructor Create(FirstName: String; LastName: String);
private
fFirstName: String;
fLastName: String;
end;
// Heros are more than ordinary people. ////////////////////////////////////
THero = class(TPerson)
public
constructor Create(FirstName: String; LastName: String; TagLine: String);
constructor Create(FirstName: String; LastName: String);
function ToString(): String; override;
private
fTagLine: String;
end; { THero }
// TPerson implementation //////////////////////////////////////////////////
function TPerson.ToString(): String;
begin
Result := 'My name is ' + fFirstName + ' ' + fLastName + '.';
end; {TPerson.ToSting}
constructor TPerson.Create(FirstName: String; LastName: String);
begin
fFirstName := FirstName;
fLastName := LastName;
end; {TPerson.Create}
// THero implementation ////////////////////////////////////////////////////
constructor THero.Create(FirstName: String; LastName: String);
begin
inherited Create(FirstName, LastName);
end; {THero.Create}
constructor THero.Create(FirstName: String; LastName: String; TagLine: String);
begin
inherited Create(FirstName, LastName);
fTagLine := TagLine;
end; {THero.Create}
function THero.ToString() : String;
begin
Result := inherited ToString() + ' I''m a hero.' + Chr(10) + fTagLine;
end; {THero.ToString}
// What we really want to do is overload Write and WriteLn just once.
procedure Write(Obj: TObject); overload;
begin
System.Write(Obj.ToString());
end; {Write}
procedure WriteLn(Obj: TObject); overload;
begin
Write(Obj);
System.WriteLn;
end; {WriteLn}
var
OrdinaryPerson: TPerson;
SpaceHero: TPerson;
GreenLantern: TPerson;
begin
SpaceHero := THero.Create('Flash', 'Gordon',
'Flash a-ah' + Chr(10) +
'Savior of the Universe' + Chr(10) +
'Flash a-ah' + Chr(10) + 'He''ll save every one of us');
OrdinaryPerson := TPerson.Create('John', 'Doe');
GreenLantern := THero.Create('Hal', 'Jordan');
WriteLn(OrdinaryPerson);
System.WriteLn();
WriteLn(SpaceHero);
System.WriteLn();
WriteLn(GreenLantern);
FreeAndNil(OrdinaryPerson);
FreeAndNil(SpaceHero);
FreeAndNil(GreenLantern);
end. { RecordWrite }
Note: all code compiled in delphi mode.