Incus J 10 Posted October 8, 2020 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
David Heffernan 2345 Posted October 8, 2020 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. 1 Share this post Link to post
Incus J 10 Posted October 8, 2020 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
Kryvich 165 Posted October 8, 2020 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
David Heffernan 2345 Posted October 8, 2020 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
Dalija Prasnikar 1396 Posted October 8, 2020 There is feature request for expanding helpers functionality https://quality.embarcadero.com/browse/RSP-13340 Share this post Link to post
Guest Posted October 8, 2020 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
Remy Lebeau 1396 Posted October 8, 2020 (edited) 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 October 8, 2020 by Remy Lebeau 1 Share this post Link to post
David Heffernan 2345 Posted October 9, 2020 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. 2 Share this post Link to post
Stefan Glienke 2002 Posted October 9, 2020 (edited) 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 October 9, 2020 by Stefan Glienke 2 Share this post Link to post
Rollo62 536 Posted October 9, 2020 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
David Heffernan 2345 Posted October 9, 2020 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
Rollo62 536 Posted October 9, 2020 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