Jump to content
Incus J

Extending string - How to call the default record helper?

Recommended Posts

I’m creating a record helper for string.

It seemed like a good idea at first, until I realised string already has a helper, and I can’t inherit from it (?)

 

So I think I need to duplicate those existing default string helper functions in my new string helper, and call into the original.  Something like this :

function TStringHelper.ToInteger: integer;
begin
  result := System.SysUtils.TStringHelper.ToInteger(Self);
end;

[dccosx64 Error] My.Str.Helper.pas(36): E2018 Record, object or class type required

Don’t laugh, am I anywhere close…?

Share this post


Link to post
23 minutes ago, Incus J said:

am I anywhere close…?

Nope. This is an endeavour that is doomed to fail. You'd have to duplicate the implementation of the standard helper if you wanted to have access to its functionality as well as that in your own helper.

 

It's been this way since helpers were added, and I have given up hoping that the issue will be addressed.

  • Sad 1

Share this post


Link to post

That's unfortunate, I did like the concept of helpers.  Really I just wanted to add a couple of extras, to make my coding a little less verbose with fewer brackets e.g.

mystring := mystring.Trim.Capitalise;

vs

mystring := TMyStringUtils.Capitalise(Trim(mystring));

 

...the flow and readability of the first version has some appeal.  I find it easier and quicker to parse.  I think adding the ability to inherit from an existing helper would make helpers more practical.  Better would be types supporting multiple helpers simultaneously.  Hey, I can dream 🙂

 

Thank you for the heads up!

Share this post


Link to post

Several years ago, I suggested adding the ability to call global functions and procedures as if they were class members of their first const parameter. For example, the standard function Trim could be used like this:

Result := '  ABCD  '.Trim;  // equals to Result := Trim('  ABCD  ');

Unfortunately, they came up with the concept of non-extensible helpers.

Share this post


Link to post
22 minutes ago, Incus J said:

I think adding the ability to inherit from an existing helper would make helpers more practical.

We all think that ......

 

C# extension methods allow types to be extended from multiple classes ..... 

Share this post


Link to post
6 hours ago, Incus J said:

Don’t laugh, am I anywhere close…?

I reluctant to add this, but asking for a laugh then here you go:

type
  StringEx = type string;

  TMyStringHelper = record helper for StringEx
    function ToInteger: Integer;
  end;
  
{ TMyStringHelper }
function TMyStringHelper.ToInteger: Integer;
begin
  Result := StrToIntDef(Self,0);
end;

//use it like this
var
  D: Integer;
 
D:= StringEx(st).ToInteger;

Ugly but does work.

Share this post


Link to post
14 hours ago, Incus J said:

It seemed like a good idea at first, until I realised string already has a helper, and I can’t inherit from it (?)

Which is funny, given that the syntax for helpers actually supports inheritance, but Delphi allows it only in class helpers, not in type/record helpers.  FreePascal proves inheritance can work in all three kinds of helpers (just not in Delphi mode, for compatibility reasons).

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

Inheritance would not be the ideal solution. That would make it impossible for two distinct libraries to extend the same type. 

 

I don't understand what is hard about having multiple helpers active and searching through them, most recently declared first. 

  • Like 2

Share this post


Link to post

Fun fact: some years ago someone (not me, not Andreas) achieved being able to inherit record helpers by simply patching one flag in the compiler. 😉

I am just saying this to emphasize that its not some technical limitation but simply the compiler does not allow it when it sees "record helper" but does when its "class helper" as otherwise its the same code.

Edited by Stefan Glienke
  • Like 2

Share this post


Link to post

Would be great to support at least kindof casting to the desired helper,

that would solve some cases where several competing helpers were all around.

 

Share this post


Link to post

Casting to a helper should never be supported. That's just ugly. May as well call a function and be done with it. You lose all the benefit of type extension if you have to cast. 

Share this post


Link to post

I agree on the ugliness, but what if type extension is too hard to get ...

What else is on the roadmap ?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×