Record helpers can do wonders for code clarity.
// Never mind the silly example
TResult = (CompletedOK, PartiallyPerformed, NothingHappened, HorriblyWrong);
function DoSomething:TResult;
begin
Result := PartiallyPerformed;
end;
How do we determine failure vs success?
if not DoSomething = CompletedOK then …?
What about Partially performed and nothing happened?
Enter the helper:
TResultHelper = record helper for TResult
function Failed:Boolean;
function Success:Boolean;
end;
function TResultHelper.Failed: Boolean;
begin
Result := (Self = HorriblyWrong);
end;
function TResultHelper.Success:Boolean;
begin
Result := not Failed;
end;
Now we can write
if DoSomething.Failed then …
Note that you also can enter the murky waters of obfuscation through helpers, but at least the murkiness will be consistent 😛
Is that satire, or what?!
That depends on the eye of the beholder 😉
Opposite of Failed is Succeeded
As I said, never mind the silly example
In plain pascal, I will define in the same unit than TResult:
const RESULT_FAILED = [HorriblyWrong];
and write a clean
if DoSomething in RESULT_FAILED then …
Sounds MUCH cleaner to me than using a record helper.
function TResultHelper.Failed: Boolean;
begin
Result := (Self in RESULT_FAILED);
end;
or
TResultSet = Set of TResult;
const
RESULT_FAILED = [HorriblyWrong];
RESULT_SUCCESS = [CompletedOK, PartiallyPerformed, NothingHappened];
type
TResultHelper = record helper for TResult
function Success(const SuccessStates:TResultSet = RESULT_SUCCESS):Boolean;
function Failed(const FailStates: TResultSet = RESULT_FAILED):Boolean; //
…
function TResultHelper.Success(const SuccessStates:TResultSet): Boolean;
begin
Result := (Self in SuccessStates);
end;
function TResultHelper.Failed(const FailStates: TResultSet): Boolean;
begin
Result := (Self in FailStates);
end;
to allow you to deviate from the defaults on need.
THorriblyWrongFrowny;
Why not create a record, with implicit conversion from the TResult, to give some methods? Could make the code even more circumvented…
type TNilHelper=record helper for nil … end; if Something.Failed …
Luddites 😉
Lars Fosdal Luddites? I not going back to GWBASIC. I will continue to happily run my Turbo Pascal in a Windows 98 command window thank you very much :p
GWBASIC? Luxury! We had to cut our own punchcards from old shoe boxes with a blunt pair of scissors and then punch holes in them with a rusty nail! And on Fridays…