Jump to content
Mike Torrettinni

Does debugger handle WITH better in latest versions, 10.3+?

Recommended Posts

At least in Delphi 10.2 WITH doesn't work in debugger, meaning debugger doesn't show record field values when hovering over them:

with MyRecord do
  FieldName := 'new';
 end'

Has this been fixed in later versions, 10.3 or 10.4? Anybody has any info is this ever going to be fixed?

Edited by Mike Torrettinni
better topic title

Share this post


Link to post

Hi...

Quote

Anybody has any info is this ever going to be fixed

...I hope not. :classic_huh: WITH is out of date.

Quote

WITH doesn't work in debugger

...this has always been so. That´s the reason why i never had a WITH in my code. :classic_wink:

Edited by haentschman
  • Like 1

Share this post


Link to post

I can't move from 10.2, yet, so I don't have newer version installed and I was just thinking if they will fix the debugger issue with WITH.

 

 

Share this post


Link to post

Hi...:classic_cool:

 

Why WITH?  How long would it take to remove all WITH?

Quote

debugger issue with WITH

...imho: The topic is since D1 so. :classic_huh:

Edited by haentschman

Share this post


Link to post
32 minutes ago, Mike Torrettinni said:

I can't move from 10.2, yet, so I don't have newer version installed and I was just thinking if they will fix the debugger issue with WITH.

It still does not work in 10.4

  • Thanks 1

Share this post


Link to post
2 hours ago, Dalija Prasnikar said:

It still does not work in 10.4

Thanks!

 

25 minutes ago, David Heffernan said:

Given that so much that is actually important is broken, this should be way down the list of priorities. 

Absolutely!

 

I had an example of a few lines of code using long named identifier and while I was replacing it with short named local variable, I was thinking of WITH, it could be nice to use it in this case.

If only the debugger worked :classic_unsure:

Share this post


Link to post
3 hours ago, haentschman said:

Hi...:classic_cool:

 

Why WITH?  How long would it take to remove all WITH?

...imho: The topic is since D1 so. :classic_huh:

I don't use it, but I used to, it would be nice to have a working feature we can decide to use or not. But if it's broken, no use for it.

 

6 hours ago, Lars Fosdal said:

I very rarely use with. Too many pitfalls.

Well, even when I used to use it, it would be with single identifier, so most of the time the issue (for me) was the debugger. I never found the use of complicated examples for WITH.

Share this post


Link to post

It doesn't need to be complicated. 

 

If the type of the variable you reference by with contains a field or property that has the same name as a local field or property - you do not get a hint or a warning, but the property set will be the on the with reference, not on the class instance doing the with reference.

 

Share this post


Link to post
20 minutes ago, Lars Fosdal said:

It doesn't need to be complicated. 

 

If the type of the variable you reference by with contains a field or property that has the same name as a local field or property - you do not get a hint or a warning, but the property set will be the on the with reference, not on the class instance doing the with reference.

 

All problems relating to with could be solved by the compiler warning about such collisions. 

  • Like 1

Share this post


Link to post

Indeed.  Such a warning should also apply to parameters and local variables.

 

program WhyNotWith;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TParam = class
  private
    FBar: Integer;
    FFoo: Integer;
  public
    constructor Create; virtual;
    property Foo: Integer read FFoo write FFoo;
    property Bar: Integer read FBar write FBar;
    procedure Dump(const Title: string);
  end;


  TOuter = class(TParam)
  public
    constructor Create; override;
    procedure Process(const Param: TParam; var Bar: Integer);
  end;

{ TOuter }

constructor TOuter.Create;
begin
  Inherited;
end;

// No warnings to be seen
procedure TOuter.Process(const Param: TParam; var Bar: Integer); 
var
  Foo: Integer;
begin
  Foo := 0; 
  Bar := 7;
  With Param
  do begin
    Bar := Bar * Bar; 
    Foo := Foo + Bar;
  end;
  Writeln('Process', ' Foo:', Foo, '  Bar:', Bar);
end;

{ TParam }

constructor TParam.Create;
begin
  Foo := 2;
  Bar := 5;
end;

procedure TParam.Dump(const Title: string);
begin
  Writeln(Title, ' Foo:', Foo, '  Bar:', Bar);
end;

procedure Test;
var
  Param: TParam;
  Outer: TOuter;
  Bar: Integer;
begin
  Bar := 9;
  Param := TParam.Create;
  Outer := TOuter.Create;
  Outer.Process(Param, Bar);
  Param.Dump('Param');
  Outer.Dump('Outer');
  Writeln('Bar ', Bar);
end;

begin
  try
    try
      Test;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    Write('Press Enter: ');
    Readln;
  end;
end.

 

Share this post


Link to post
1 hour ago, David Heffernan said:

All problems relating to with could be solved by the compiler warning about such collisions. 

I was hoping new LSP would sort this out. Maybe in future updates. Never give up hope on Delphi 🙂

Share this post


Link to post

Better get rid of with in your code where possible...

Nick Hodges back then even wanted to deprecate with so I wouldn't expect EMBT to invest much time in improving the debugger in this area.
I guess there are things waiting to be done with more worth for us developers...

Share this post


Link to post
4 hours ago, Mike Torrettinni said:

I was hoping new LSP would sort this out. Maybe in future updates. Never give up hope on Delphi 🙂

LSP isn't about changing the language warning definitions.

 

Never give up hope is a strange message. Keep hoping if that hope is justified. 

Share this post


Link to post

Embarcadero's code examples are full of WITH usage, so probably unlikely they will deprecate it.

Here is example of a double(triple?)-nested WITH usage: http://docwiki.embarcadero.com/CodeExamples/Sydney/en/ActiveControl_(Delphi)

 

I checked a few components source code and search found1000s of occurrences of WITH usage.

 

I didn't even know about WITH ... AS .. DO.:

 

with GetComponent as TPanel do
    case Index of
      0: Result := IfThen(Expanded, 'Collapse Panel', 'Expand Panel');
      1: Result := IfThen(FlipChangeArea <> faHeader, 'Header Click', 'Button Click') + ' can Toggle' ;
    end;

 

Edited by Mike Torrettinni

Share this post


Link to post
3 minutes ago, Mike Torrettinni said:

I didn't even know about WITH ... AS .. DO.:

 

"with as do" is not a thing in its own right. There is with (expr) do. And here we see as used in an expression. We are just composing different aspects of the language. 

  • Thanks 1

Share this post


Link to post
Just now, David Heffernan said:

"with as do" is not a thing in its own right. There is with (expr) do. And here we see as used in an expression. We are just composing different aspects of the language. 

Aha, OK, makes sense. Everyday something new.

Share this post


Link to post
7 minutes ago, David Heffernan said:

"with as do" is not a thing in its own right. There is with (expr) do. And here we see as used in an expression. We are just composing different aspects of the language. 

OK, after you mentioned it (expr), I had to test if function result can be used with WITH, and it works:

type
  TResult = record
    A,B,C: string;
  end;

function GetResult: TResult;
begin
  //
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  with GetResult do
    Caption := A;
end;

I never did and never will use it, but interesting to know.

Edited by Mike Torrettinni

Share this post


Link to post

Add a Caption: string to TResult and try again.

It will set TResult.Caption to A, and you get no hint or warning that there is a name space collision.

 

Using inline variable declarations - you can eliminate with without a lot of extra code.

procedure TForm1.FormCreate(Sender: TObject);
begin
  var r := GetResult;
  Caption := r.A;
end;

 

  var p := GetComponent as TPanel;

 

  • Like 2

Share this post


Link to post
7 hours ago, Lars Fosdal said:

Add a Caption: string to TResult and try again.

It will set TResult.Caption to A, and you get no hint or warning that there is a name space collision.

 

Using inline variable declarations - you can eliminate with without a lot of extra code.


procedure TForm1.FormCreate(Sender: TObject);
begin
  var r := GetResult;
  Caption := r.A;
end;

 


  var p := GetComponent as TPanel;

 

And even without the inline variables, it is pretty minor compared to the pain which comes with with.

Share this post


Link to post
On 7/21/2020 at 3:40 AM, Lars Fosdal said:

Using inline variable declarations - you can eliminate with without a lot of extra code.

I can't wait to try this out, unfortunately probably in 10.5, not sooner. Maybe they will improve debugging WITH by then, too 🙂

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

×