Jump to content

Recommended Posts

Hi All,,

 

Just a silly question 🙂

 

if I can write this code,  what is the pros and cons about it ?

 

From a lasy view, you don't need to create it, free it, ..

 

Thanks 

 

Patrick

 

  prTxt = ^rTxt;
  rTxt = record
  private
    FValue : string;
    function GetAsText : string;
  public
    property Value  : string read FValue;
    property AsText : string read GetAsText;
    function WithValue(const aValue : string) : prTxt;
  end;

 

 

 

Share this post


Link to post

The final function can't be right. It should be a static class function, but that's not enough. What would it return? A pointer to what instance? You'd need to allocate an instance somewhere. 

 

I'd use a helper record to get around the inability to forward declare value types.

Share this post


Link to post

Hi David, 

Thanks for your reply ; that's both function (and btw working)

 

{ rTxt }

function rTxt.GetAsText: string;
begin
  result:=StringReplace(FValue,'\r\n',CRLF,[rfReplaceAll]);
end;

function rTxt.WithValue(const aValue: string): prTxt;
begin
  FValue:=aValue;
  result:=@Self;
end;

 

How should I write it then ?

 

Share this post


Link to post
37 minutes ago, PatV said:

How should I write it then ?

What are you aiming to achieve...? Returning a pointer to Self doesn't give any obvious benefit - if the rTxt instance is statically defined, the validity of a pointer to it will remain restricted to the scope of the instance variable. In other words, this sort of code is invalid -

function Foo(const Value: string): pTxt;
var
  Inst: rTxt;
begin
  Result := Inst.WriteValue(Value);
end;

procedure Test;
var
  Ptr: pTxt;
begin
  Ptr := Foo('Bad code - if the next bit "works", it will only be by luck');
  ShowMessage(Ptr.AsText);
end;

Conversely if rTxt is dynamically allocated (New and Dispose standard procedures), then by definition you lose the 'lazy' benefit you hoped to achieve. If your intent was that WriteValue should return a new instance, then (as David said) the method needs to be a class static method (or a constructor), and return the instance type (not a pointer):

type
  fTxt = record
  // ...
    class function WriteValue(const Value: String): fTxt; static;
  end;

class function fTxt.WriteValue(const Value: String): fTxt;
begin
  Result.FValue := Value;
end;

function Foo(const Value: string): fTxt;
begin
  Result := fTxt.WriteValue(Value);
end;

procedure Test;
var
  Inst: fTxt;
begin
  Inst := Foo('OK code - if next bit works genuinely');
  ShowMessage(Inst.AsText);
end;

 

Share this post


Link to post

Why return a pointer to self? You just risk having that pointer outlive the record instance. 

 

Make this a constructor or a static class function that returns a new instance. 

 

BTW I remembered wrongly before. No need for a helper to implement a static class function that returns rTxt. 

Share this post


Link to post
Posted (edited)

 I could assume that if the structure in question is more complex and the snippet we see is a sample, the use of withValue() would be part of a bigger set of stuff where the structure is set using method chaining...

 

e.g. myrec.withValue('abc').withNum(123)...

 

returning a pointer would be slightly more optimal as the delphi syntax should still allow the chaining with the '.', and the original structure would be referenced rather than copies being made if the result of each withXyz() was an actual record.

 

if part of the question is about record vs class, well records in Delphi can be heap or stack based, where classes in Delphi are heap based. Assignment of a record in general, even in a method chain would result in copies, vs using a class would simply be passing a pointer around.

 

As David mentioned however, it is a trivial scenario, just using a constructor would do. Using method chaining is sometimes an opinion piece, commonly used when using builder type patterns.

Edited by darnocian

Share this post


Link to post

Yes Darnocian, it was the goal, add fluent interface to record, so the main difference is that passing a record is a copy compare to a class

 

Thanks

 

Patrick

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
Sign in to follow this  

×