tags:

views:

607

answers:

9

Hi I am have a problem debugging code that uses a ‘WITH’ statement in BDS 2006 The debugger will not show the values of the variables with in a class or record. Am I doing something wrong or does BDS 2006 have a bug ?

type
  TNumber = class
      Num: Integer;
  end;

implementation

{$R *.dfm}

var
   MyNumber: TNumber;

procedure TForm2.FormCreate(Sender: TObject);
begin
   MyNumber := TNumber.Create;
   MyNumber.Num := 10;   /// MyNumber.Num Can be seen with debugger
   with  MyNumber do
   begin
     Num := Num +1 ;           /// Num is not seen by the  debugger
     MyNumber.Num := Num +1 ;  /// MyNumber.Num is seen but Num is not seen by the  debugger
   end;
end;

EDIT:

Sure one can use the full name of the variable But things become very messy if you have a complex structure with more than one level

+8  A: 

The Debugger cannot make the connection between the variable shown in the source-code that you want to examine and the related with-statement, when you mouse-over the variable. You will have to examine the values in the debug-watch window and specify the complete variable there, e.g. MyNumber.Num.

Holgerwa
I think "cannot" is too generous. I would say that it "does not" as designed.
Argalatyr
+4  A: 

"With" introduces ambiguities and can cause more problems than it solves. Consider simply not using it.

Castalia has a refactoring that helps remove them.

Bruce McGee
+11  A: 

With is considered by many one of those language features that falls into the "just because you have it doesn't mean you have to use it" category. There are very few occasions I where I'd give it house-room - I've found one or two cases where it's use is essential when using extremely complex multi-level structures where the compiler doesn't do quite as you'd expect without it and it is easier to include, but in 10 years of coding Delphi I think these could be counted on the fingers of one hand.

It does tend to get used rather a lot in examples as the code certainly looks cleaner, but in practice the maintenance impact of figuring out if a variable is simple or part of a structure when reviewing code you didn't write or haven't used for a period easily outweighs that. The know issues with the debugger on every version of Delphi I've ever used is the clincher.

Cruachan
I'd love to see the example where it's necessary.. I've done Delphi for 10 years too, and have spent 9.5 of them removing WITH clauses, and substituting for aliases, as per Fabricio's answer
Ben Laan
As I recall it was on D6 with something like a multiple level structure where one of the child nodes was a pointer - to another structure. Without the With clause it didn't seem possible to deploy any syntax that accessed an item in the second structure.
Cruachan
Ah, aliases... I was trying to remember that word when writing my answer .... ;-)
Fabricio Araujo
+5  A: 

The debug problems with the with statement are known. That's one of the reasons I remove them when I see them. In my oppinion you should never improve coding speed at the cost of maintainability.

A common construct I see a lot (and learned to hate) is:

with TMyObject.Create do
  try
    Method1(blah, blah, blah);
    Method2(blah, blah, blah);
  finally 
    Free;
  end;

It is even possible to add more constructs in the with statement:

with A, B, C, D do
  // Aargh!

But then again, there are sometimes valid uses for the with statement if you can replace:

A.B.C.D.E.Method1;
A.B.C.D.E.Method2;
A.B.C.D.E.Method3;
A.B.C.D.E.Method4;
A.B.C.D.E.Method5;
A.B.C.D.E.Method6;

With

with A.B.C.D.E do begin
  Method1;
  Method2;
  Method3;
  Method4;
  Method5;
  Method6;
end;

Although the use os A.B.C.D.E is a bit questionable, it tend to be "the delphi way." But now with class helpers, we can have a perfectly valid solution:

TAHelper = class helper for TA
public
  procedure Method1;
endl

procedure TAHelper.Method1;
begin
  // You can (should) add sanity checks here.
  B.C.D.E.Method1;
end;

So now you can use:

A.Method1;

Which is a lot better in my opinion.

Gamecat
I do not like class helpers that much... I use them only when I'm on a hurry and don't have time to a more clear but much longer solution (which means edit many files, alter classes, etc). Class helpers make code more difficult to follow.
Fabricio Araujo
+4  A: 

I use With..do rarely and tend to do like this

var
  Sc : TE_Type;
begin
  Sc := A.B.C.D.E;
  sc.Method1;
  sc.Method2;
  sc.Method3;
  sc.Method4;
  sc.Method5;
  sc.Method6;
end;

Of course, a decent name for Sc won't hurt. And I think it's clearer than with..do and debugger finds itself much better. So, I like much that 'shortcut' variables.

Fabricio Araujo
ACK. As long as we don't have a "with" with alias or a "using" that's the best solution in most cases IMHO.
Ulrich Gerhardt
A: 

I'm fully convinced that the dreaded "with" clause was included just so book writers didn't have to have all those ugly TWinComponent strings in their example code. In real life, outside of code snippets and textbooks, there is almost no good reason to use "with".

The primary reason is it breaks the debugger. It would be very impractical for the debugger to evaluate entire clauses when finding the value of a variable, so its not a bug, its just unsupported in all delphi debuggers I know about. If you're like me, stuck maintaining hundreds of thousands of lines from a programmer that basically copied everything out of the textbook, it makes debugging a living hell.

Bottom line, DON'T USE WITH-CLAUSES... EVER!

David Dombrowsky
The primary reason is because it causes scope resolution problems if you're not very, very careful with it. Breaking the debugger is a secondary annoyance that just compounds the problem.
Mason Wheeler
+4  A: 

The with statement is syntactic NutraSweet: It tastes a lot like syntactic sugar, but leaves a bad aftertaste and turns out to actually be harmful in the long term. It's best to just not use it.

Mason Wheeler
ROFL!!!!!! hahahahahahaha!!!! Great!
Fabricio Araujo
A: 

With is not a bad practice at all. The only bad thing is that you can not debug easily that lines, but if you use it carefully there is no problem at all. May be its not a good practice for juniors, but if you know where to use it, its just ok.

Lets EMBA improve it in any way they can to avoid the common rants about it.

DelphiWithDefender