Jump to content
Mike Torrettinni

How to extend/add helpers to for record function?

Recommended Posts

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 by Mike Torrettinni

Share this post


Link to post

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 by David Heffernan

Share this post


Link to post
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

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.

  • Thanks 1

Share this post


Link to post

Your helper is not going to work because what you want is a string helper (since the return value of GetAttribute is a string. 

  • Thanks 1

Share this post


Link to post
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

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

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

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

×