Class Helpers and Record Helpers
A class or a record helper is a type that - when associated with another class or a record - introduces additional method names
and properties that may be used in the context of the associated type (or its descendants).
Helpers are a way to extend a class without using inheritance, which is also useful for records that do not allow inheritance at all.
A helper simply introduces a wider scope for the compiler to use when resolving identifiers. When you declare a class or a record
helper, you state the helper name, and the name of the type you are going to extend with the helper.
You can use the helper any place where you can legally use the extended class or record.
Class and record helpers provide a way to extend a type, but they should not be viewed as a design tool to be used when
developing new code. For new code you should always rely on normal class inheritance and interface implementations.
Using Helpers with Pas2JS
Smart Mobile Studio supports helper objects for various elements, including classes, records and arrays.
Helper’s are extremely
valuable in leveraging complex data-structures. This is a very powerful addition to Smart’s already impressive list of
"must have" features when working with javascript. Features that no existing javascript framework or utility provides.
Why not just use another interface?
Presumably because you are not in a position to modify the implementing object.
That's why one uses helpers / extension methods.
Helpers in Smart Pascal are a generalization of Delphi’s class helpers and can be applied to (almost) any type,
even to built-in types. You can also have multiple helpers per type. The syntax is as following:
type
TMyHelper = helper for sometype
private
// private helper methods, class vars & class consts
public
// public helper methods, class vars & class consts
end;
|
Smart Mobile Studio supports helper objects for various elements, including classes, records and arrays.
You can have helpers for base types, classes, records, interfaces or arrays. For instance if you write:
Code Example: Declaring a helper for base type float
type
TFloatHelper = helper for Float
const NPI = 3.141592;
function ToStr: String;
end;
function TFloatHelper.ToStr : String;
begin
Result:= FloatToStr(Self);
end;
procedure TForm1.W3Button2Click(Sender: TObject);
var ReturnValue : Float;
begin
ReturnValue := 2.71;
ShowMessage((ReturnValue * TFloatHelper.NPI).ToStr); //8.51371432
ShowMessage(TFloatHelper.ToStr(ReturnValue * Float.NPI)); //8.51371432
ShowMessage( (ReturnValue * ReturnValue.NPI).ToStr ); //8.51371432
end;
|
Result will be: 8.51371432
---------------------------
You can write literal expressions such as:
Float.NPI
TFloatHelper.NPI
myFloatVar.ToStr
TFloatHelper.ToStr(myFloatVar)
It is possible to have class methods in helpers; for types with a meta-symbol, Self will be that meta-symbol.
(for instance, for a TObject helper, Self would be TClass), for others (like Float), Self will not be defined.
For records, Self is passed as a const parameter therefore record helpers cannot modify the record being operated upon.
Smart also supports a simplified helper syntax where you just declare a method and mark it as a helper.
You can for example declare a following helper called Prepend and then use it on any data of the string type.
Code example: Declaring method as a helper
function Concat(s: string; prefix: string): string; helper Prepend;
begin
Result := prefix + s;
end;
procedure TForm1.W3Button3Click(Sender: TObject);
var s : String;
begin
s:= 'Hello world';
WriteLn(s); // Hello world
Writeln(s.Prepend('ABC:')); // ABC:Hello world
Writeln(('my string').Prepend('*** ')); // *** my string
end;
|
Hello world
ABC:Hello world
*** my string
-----------------
The following code demonstrates the declaration of a class helper (record helpers behave in the same manner):
A class helper example.
Class and Record helper example: how old are you?
Multiple class helpers within scope are supported!
That is, MORE THAN ONE class helper for a given class may be in scope at any time. For instance, if you have two helpers in
scope, ALL OF THEM will be recognised by the compiler. You won't get any warnings or even hints about any other helpers that
may be hidden.
Multiple class helper within the same class scope are supported in Pas2JS
Added a bunch of helpers for String, Integer, Float and Boolean type.
See https://code.google.com/p/dwscript/wiki/BaseTypes for a full list.
NOTES:
· | Class helpers can be stored in a separate unit, so you can add your own nifty class helpers. |
Be sure to give these units a easy to remember name like ClassesHelpers for helpers for the Classes unit.
· | There are also record helpers. |
· | Helpers on functions pointers or delegates types aren’t yet allowed, mostly because of ambiguity. |
Code example: Helpers on functions pointers or delegates are not supported.
type
TFunc = function : Integer;
TFuncHelper = helper for TFunc // this is not allowed
function ToString2 : String;
end;
TIntegerHelper = helper for Integer
function ToString2 : String;
end;
var f : TFunc;
f.ToString;
|
The f.ToString2 could be understood as meaning TFuncHelper.ToString2(f) or TIntegerHelper.ToString2(f())
if helpers on function pointers were allowed.
|