How to see the Generic Array's name while debugging? - arrays

I started using a lot of generics but now I find it harder and harder to debug, to know which array is actually begin worked on. See example:
Type
TData = record
DataID:integer;
DataName:string;
end;
var DataArr1,DataArr2,DataArr3:TArray<TData>;
procedure WorkOnData(Data:TArray<TData>);
begin
if Data = DataArr1 then // <-- PARKING HERE ON DEBUG I CAN SEE ARRAY DATA, BUT NOT WHICH ARRAY IT IS
ProcessA(DataArr1)
else if Data = DataArr2 then
ProcessB(DataArr2)
else if Data = DataArr3 then
ProcessC(DataArr3);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender = Button1 then
WorkOnData(DataArr1)
else if Sender = Button2 then
WorkOnData(DataArr2)
else if Sender = Button3 then
WorkOnData(DataArr3);
end;
So, I can identify the array by comparison to get True/False:
Data = DataArr1
but, this doesn't give me info which array it is, before the comparison. So, I would need to put breakpoints after each comparison to know which one is True.
These obviously don't work:
Data.Name
TArray<Data>.Name
Is there any other way to know which array has been passed that I can see in debugger (Watch)?
Answer/Solution:
For anybody who faces the same problem, question: As Remy says in accepted answer that what I would like to achieve, is not possible. OK, now the quick workaround is to put the comparison (Data = DataArr1) into Watch and see which one resolves to True. Not best, but still usable as now we can see which array is actually being used.

There are no variable names once the code gets compiled. When you debug WorkOnData(), the only variable name it can display is Data, and there is no way for the debugger to know what Data is pointing at without evaluating an expression that you provide. So no, what you are asking for is basically not possible.
What you would likely have to do is wrap your array inside of another record that has a Name string field, and then pass that record around as needed. When you inspect it in the debugger, you would see its Name value.

Related

Swift: Return Backendless to table

Im having a problem on putting my received data(from backendless) to a tableview.
As you can see on the image i have get data from Backendless and i have checked the data with print and it works.
Now i want to put the data to my tableView, but it does not work as you usually do with making an array in the beginning and then just put return.Sub.count.
Any idea how to do it?
You should declare
var Sub = [String]()
underneath your tableView class declaration (At the very top)
Then, in your function,
fetchingAllUsers()
delete the "var" keyword, and you should be fine.
Also, it'd help if you posted all of your code if you need me to be more specific.

Should array's length be set to zero after use?

I'm wondering if setting Delphi's array's length to 0 after use is a correct practice or not.
var
MyArray : array of TObject;
begin
SetLength(MyArray, N);
// do something with MyArray (add items and use it..)
SetLength(MyArray, 0);
end;
Is there a reason why I should set length to 0?
Assuming that MyArray is a local variable then there is no reason at all to finalise the variable in the code presented. As soon as the variable leaves scope, it will be finalised. There's nothing to be gained by doing so explicitly.
Sometimes however, you have a variable whose scope extends significantly longer than your use of the array. In those scenarios it can be useful to finalise the variable as soon as you have finished with it so that the memory is returned.
Personally I would prefer
MyArray := nil;
or
Finalize(MyArray);
which in my opinion more readily jump out as finalisation statements. Your
SetLength(MyArray, 0);
can look like you are allocating when skimming the code.
Dynamic arrays are automatically freed when nothing is referencing it.
I would prefer the following method if you need to do this manually. This looks clear to me than other methods.
MyDynamicArray = nil;
It sets the natural environment of zero reference and let the memory manager to free it in due course.

Call to SetLength returns nil

There is a procedure looking like this:
procedure blabla;
var buffer: array of byte;
begin
Setlength(buffer, 10);
Setlength(buffer, someinteger);
end
after both calls buffer is still nil <- this is my problem
I normally consider myself an experienced programmer and i use this fundamental method on various other occasions. This is driving me nuts.
Did anyone of you have similar issues in the past?
If so, what was the problem?
My code is somewhat spaghetti because i had changed any line that seemed suspicious, but here is the full code:
full procedure
#Edit:
i have this code in another part of the same project:
procedure interleaveVertexes;
var
interleavedArray: array of TVec3Coord2;
begin
SetLength(interleavedArray, vertexcount);
end;
and it works.. like it should
i was using gdb and the lazarus ide to debug and apparently..
Both of them dont like variables called 'buffer' or 'Data'.
I understand the lazarus ide internally is using gdb anyway.
Even a variable is just named 'h' wouldn't let itself be inspected properly.
i just renamed them to 'buffa' and 'howdy' and now it seems to be working.
Got there by doing old-fashioned print-debugging and storing the pointer of my array in a cardinal variable. There they were fine. (Apart from the actual content of the array)
annoingly funny

Accessing variable from other class returns null

I did a separate levelData class to be able to flexibly add levels. I was happy with it until my supervisor ordered me to convert my levelData into XML. I did an XML version of the levelData's data (question, answers, correct answer...). I used the old class and converted it so that it fetches the XML.
All seems well, I did traces of my answers array and it printed nicely...
But the headache started when I tried this.
// This code appears in a different class with
// currentLvl:LevelData initialized in the constructor.
quizHolder.ansA.ansHud.text = currentLvl.choices[1];
quizHolder.ansB.ansHud.text = currentLvl.choices[2];
quizHolder.ansC.ansHud.text = currentLvl.choices[3];
quizHolder.ansD.ansHud.text = currentLvl.choices[4];
// BTW, I can't make a for loop to do the same function as above. So wierd.
I tried to run it. it returned:
TypeError: Error #2007: Parameter text must be non-null.
at flash.text::TextField/set text()
at QuestionPane/setQuiz()
at QuestionPane/setQuestion()
at QuestionPane()
at LearningModule()
Where did I go wrong? I tried making a custom get function for it, only to get the same error. Thanks in advance. If I need to post more of the code, I will gladly do so =)
LevelData Class in PasteBin: http://pastebin.com/aTKC1sBC
Without seeing more of the code it's hard to diagnose, but did you correctly initialize the choices Array before using it? Failing that I think you'll need to post more code.
Another possible issue is the delay in loading the XML data. Make sure your data is set before QuestionPane tries to access it.
When did you call
quizHolder.ansA.ansHud.text = currentLvl.choices[1];
quizHolder.ansB.ansHud.text = currentLvl.choices[2];
quizHolder.ansC.ansHud.text = currentLvl.choices[3];
quizHolder.ansD.ansHud.text = currentLvl.choices[4];
these? You load the XML and on complete you fill the array, what is correct. but is the XML loaded and parsed to the time when you access (fill the TextFields) the choices array already?

Convert RTF image data to plain text (SQL Server and Dephi BDS 2006)

Been struggling with this one for a while. We have a old table (SQL Server) that has image type data. I want to get the text.
So far this is what I've done.
Try to convert or cast it (not allowed)
Try to bring over the data into delphi by calling a SP (I got to the point of having the data assigned to a variant)
Looked into a RTF to text function (found something here on SO, if i can just get the image data into a string).
This is the code I have so far. It's attached to a button click for now (will be running in a service). I think the assignment to the report var is not right, and SetString may not be right either. I'm not even sure if i am going about this the right way.
var
report: array of byte;
s: string;
begin
ADOStoredProc1.Parameters.ParamByName('#EncounterID').Value := '7';
ADOStoredProc1.Open;
while not ADOStoredProc1.EOF do
begin
report := ADOStoredProc1.FieldByName('Report').Value;
SetString(s, PAnsiChar(#report[0]), length(report));
Memo1.Lines.Add(s);
ADOStoredProc1.Next;
end;
I'm a little confused by "RTF image". Do you mean RTF text? Or an image (picture)? From the code, I'm suspecting the former...
I'm not sure why you're using an array of byte and then immediately putting that into a string.
This should work just as well (actually, better, because it doesn't use Value (which is a Variant conversion) and avoids the SetString function call):
while not ADOStoredProc.Eof do
begin
Memo1.Lines.Add(ADOStoredProc1.FieldByName('Report').AsString;
ADOStoredProc1.Next;
end;
You'll probably get the RTF formatting in the memo this way, though. If you're trying to strip the formatting, you'll need to use a TRichEdit instead, and use the EM_STREAMIN message to add the content, and then use the TRichEdit.PlainText property. There's an example of doing that here.

Resources