1

(Based on comments I have edited the question to focus on the actual code part causing the issue, and added a section at the end)


This is the local variables window in my Delphi 10.3.4 Win32 app, note that lData is missing:

image

The breakpoint corresponding to that screenshot is on the if EmptyJSONArray(lData) line at the end of the next code snippet:

function TLoketAPI.GetOneBatch(AJSONToXML: TJSONToXML; const ASelProps: TSelectionProps; var ABatchCount, AStatusCode: Integer): Boolean;
var
   lURL,
   lNextID,
   lData      : String;
   lLogHTTP   : TLogHTTP;
begin
   Result := false;
   if FAbort then Exit;
   lLogHTTP := TLogHTTP.Create(nil);
   Result := false;
   if ABatchCount = 0 then
      lNextID := ASelProps.GetNextIDValue
   else
      lNextID := ASelProps.GetSameIDValue;
   lURL := StringReplace(ASelProps.URL,'{id}',lNextID,[rfReplaceAll,rfIgnoreCase]);
   if ABatchCount <> 0 then 
      if Pos('?',lURL) = 0 then lURL := lURL + '?pageNumber=' + IntToStr(ABatchCount+1)
                           else lURL := lURL + '&pageNumber=' + IntToStr(ABatchCount+1);
   try
      SetHTTPJSONProperties(lLogHTTP);
      try
         lLogHTTP.Get(lURL);
         if FAbort then
             Exit;

         lData := lLogHTTP.TransferredData;

         if FSaveJSON then
         begin
            lBatchCount := ABatchCount;  
            TThread.Synchronize(nil,
                                procedure
                                begin
                                   if lNextID = '' then 
                                      SaveToJSONFile(Format('%s batch (%d)',[ASelProps.TextID,lBatchCount]),lData)
                                   else
                                      SaveToJSONFile(Format('%s (%s) batch (%d)',[ASelProps.TextID,lNextID,lBatchCount]),lData);
                                end);
         end;
         if EmptyJSONArray(lData) then

lData contains valid data returned from the logHTTP call.

At the breakpoint (or anywhere else in the routine), lData does not show up in the local variables and cannot be inspected or watched.

The IDE gives:

E2003 Undeclared identifier: 'lData'

This stuff is running in the main thread, optimization is off.

If I comment out the TThread.Synchronize, lData can again be inspected/watched.

What is going on here?


(Added) In the comments, Remy and Dalija suggested that anonymous procedure as the reason, and linked this to the Embarcadero issue RSP-22924 Watch shows undeclared identifier for captured local variables (also reported under RSP-21917).

I still don't get it though: RSP-22924 was edited to change its type to Feature. Feature? It looks like a bug to me.
And: (How) can this behavior be prevented? I'd really like to inspect lData.

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
  • @JanDoggen what does the *rest* of `GetOneBatch()` look like? Any chance that `lData` is being captured in an anonymous procedure in code you *haven't* shown yet? – Remy Lebeau Aug 10 '20 at 14:46
  • 2
    I don't see that in your code (or I missed it... waiting for new glasses), but same thing happens if local variable is captured by anonymous method https://quality.embarcadero.com/browse/RSP-22924 – Dalija Prasnikar Aug 10 '20 at 15:24
  • The declaration of LogViaSynchronize might be helpful here. – Uwe Raabe Aug 10 '20 at 15:30
  • @remy Indeed a `TThread.Synchronize`. I have edited the question because I still don't understand what's going on here. – Jan Doggen Aug 11 '20 at 07:23
  • 1
    @JanDoggen see [Variable Binding Mechanism](http://docwiki.embarcadero.com/RADStudio/en/Anonymous_Methods_in_Delphi#Variable_Binding_Mechanism) and [How are anonymous methods implemented under the hood?](https://stackoverflow.com/questions/39955052/). Since `lData` is being captured, it is not actually a local variable to `GetOneBatch()`, which is why you can't see it. It is actually a member of the implementation object behind the anonymous procedure. If you look closely, you will see that `lNextID` is also missing from the Watch window, too. Because it is also being captured. – Remy Lebeau Aug 11 '20 at 14:35

0 Answers0