Mike Torrettinni 198 Posted August 20, 2020 (edited) Not sure if this is possible, or very simple: I have record TXMLNode (a 3rd party xml library) that has function GetAttribute(name): string. I would like to use .ToInteger string helper when getting integer value, but this fails when result is empty. (I already added GetAttributeAsInteger into the source code, but from the thread the other day, suggestion was to leave the 3rd party source code intact and extend whatever needs extending) Here is a record: // very shortened version TXMLNode = record ... public function GetAttribute(const aName: string): string; end I would like to use it like : Rec.ID := vXMLNode.GetAttribute('id').ToInteger; // I prefer not to use StrToIntDef(...,0) But this fails when 'id' attribute is empty or it doesn't exist. I know how to add record helper to simple Enum, but this is not as simple. I was trying something like this, but this is not correct: TXMLNodeHelper = record helper for TXMLNode function ToInteger : string; end; function TXMLNodeHelper.ToInteger : string; begin // if Self.GetAttributeName(??) = '' then // Result := 0 // else // Result := Self.GetAttributeName(??).ToInteger; // or, in this case I would use StrToIntDef, becasue is jsut in this place and I can use .ToInteger everywehre in my code // Result := StrToIntDef(Self.GetAttributeName(??), 0); end; Any suggestion, more than welcome. If this is not possible, I will just leave modified source as it is. Edited August 20, 2020 by Mike Torrettinni Share this post Link to post
David Heffernan 2345 Posted August 20, 2020 (edited) You have to pass the attribute name to the helper function. Also, don't call GetAttribute twice. Store the return value in a local variable. Edited August 20, 2020 by David Heffernan Share this post Link to post
Mike Torrettinni 198 Posted August 20, 2020 21 minutes ago, David Heffernan said: You have to pass the attribute name to the helper function. Also, don't call GetAttribute twice. Store the return value in a local variable. Even if I try this: TXMLNodeHelper = record helper for TXMLNode function ToInteger(aName: string): integer; end; function TXMLNodeHelper.ToInteger(aName: string): integer; var vValue: string; begin vValue := Self.GetAttribute(aName); if vValue = '' then Result := 0 else Result := vValue.ToInteger; end; vID := vNode.GetAttribute('id').ToInteger; helper ToInteger doesn't get executed. I think something is missing here, shouldn't I be actually extending GetAttribute function and not the whole TXMLNode record? Share this post Link to post
David Heffernan 2345 Posted August 20, 2020 The helper is on the node. So you’d need to call vNode.ToInteger(‘Id’). I think you could do with a better name for the helper function. 1 Share this post Link to post
Vincent Parrett 750 Posted August 20, 2020 Your helper is not going to work because what you want is a string helper (since the return value of GetAttribute is a string. 1 Share this post Link to post
Mike Torrettinni 198 Posted August 20, 2020 58 minutes ago, David Heffernan said: The helper is on the node. So you’d need to call vNode.ToInteger(‘Id’). I think you could do with a better name for the helper function. Yes, I see. I didn't explain it well enough, I don't need to vNode to work with custom ToInteger, but vNode.GetAttribute(name). 57 minutes ago, Vincent Parrett said: Your helper is not going to work because what you want is a string helper (since the return value of GetAttribute is a string. I was afraid this is the reason. So, I can't do it, because string already has a helper. Share this post Link to post
Mike Torrettinni 198 Posted August 21, 2020 OK, now that I know I can't create helper on TXMLNode.GetAttribute(name): string to work with .ToInteger, I can add GetAttributeAsInteger, like this : TXMLNodeHelper = record helper for OXmlPDOM.TXMLNode function GetAttributeAsInteger(aName: string): integer; end; function TXMLNodeHelper.GetAttributeAsInteger(aName: string): integer; var vValue: string; begin vValue := Self.GetAttribute(aName); if vValue = '' then Result := 0 else Result := vValue.ToInteger; end; And now I can delete the same GetAttributeAsInteger from the source of TXMLNode and have the unit in original state, great! 🙂 Share this post Link to post
ŁukaszDe 38 Posted August 21, 2020 One more, add const for argument aName. 1 Share this post Link to post
David Heffernan 2345 Posted August 21, 2020 6 hours ago, Mike Torrettinni said: OK, now that I know I can't create helper on TXMLNode.GetAttribute(name😞 string to work with .ToInteger, I can add GetAttributeAsInteger, like this Yes. This is what I said in my earlier comments. Share this post Link to post
Mike Torrettinni 198 Posted August 21, 2020 4 hours ago, David Heffernan said: Yes. This is what I said in my earlier comments. Yes, at the time I wasn't sure what is the right approach to start with, now I know that we were thinking the same thing, I just didn't know it 🙂 Great minds think alike 😎 Share this post Link to post
Mike Torrettinni 198 Posted August 21, 2020 5 hours ago, ŁukaszDe said: One more, add const for argument aName. Thanks, good eyes! Share this post Link to post
Fr0sT.Brutal 900 Posted August 21, 2020 Side note: in general, empty string <> 0 number. Using this helper for all attributes you can ignore invalid input which could be sometimes undesirable Share this post Link to post