Helpers

Top  Previous  Next

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 SmartMS

 

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 recordsSelf 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 SmartMS

 

 

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.