RTC Forums
November 10, 2024, 09:07:15 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Bug Report: array.count is not right in script when element is record  (Read 4542 times)
xin.chang
RTC License
***
Posts: 5


« on: August 05, 2017, 07:51:20 AM »

My script is:

Code:
<?
  $x := foo(3);
  $y := foo(1);
?>
x = <?  $x.count ?>
y = <?  $y.count ?>

function foo, just return an array contains records as below:

Code:
procedure TForm1.RtcFunction1Execute(Sender: TRtcConnection; Param: TRtcFunctionInfo; 
  Result: TRtcValue);
var
  i: Integer;
begin
  Param.map(0, 'i');

  with Result.NewArray do begin
    for i := 0 to Param.Value['i'] - 1 do begin
      with NewRecord(i) do begin
        asInteger['id'] := i;
        asString['name'] := 'N' + IntToStr(i);
      end;
    end;
  end;
end;

after executed:

Code:
x = 3
y = 2 <-- WRONG, ought to be 1

if it's a simple array(contains integer or string), the count is right, it goes wrong only when the element of array is record.
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: August 05, 2017, 10:19:54 AM »

Well, technically speaking, what you've discovered there is an undocumented feature of the RTC Scripting Engine.

Because every single line of code and text inside a RTC Script is an element inside an Array, when you execute an assignment or any operation with one or more elements inside a RTC Script (to reduce command structure depth and simplify operations with brackets and single-element arrays), all arrays with a single element are automatically collapsed, so you get the actual element inside the array, instead of the entire array. At the same time, all arrays with zero elements used in opertions other than the assignment are auto-freed, returning NULL.

In other words, because your function foo(1) returns an Array with only one element and the assignment operator automatically extracts that element contained in the array, executing $y:=foo(1) inside RTC Script results in the $y variable to contain the record you've stored inside the array, instead of the entire array returned from froo(1). And because that record contains 2 elements, $y.count returns 2.

Anyway ...

I've released an update for the RTC SDK now (v8.21) to extend the "TRtcScriptEngine" class with a new "AutoCollapseArrays" property (default=TRUE), so you can disable this feature to get the results you expected when executing your Script, but please keep in mind that doing this could have negative side-effects in your Scripts, so make sure to test the rest of your Scripts if you want to use them with AutoCollapseArrays=FALSE.

As an alternative, instead of disabling the AutoCollapseArrays feature by setting the property to FALSE, you could try chaging your Scripts and Remote Functions which are currently returning an Array containing one or more Records to return a DataSet. This would keep your Scripts and Remote Functions compatible with the default behavior of the RTC Scrpiting Engine (AutoCollapseArrays=TRUE) and reduce the amount of memory used, because field names are stored separately in DataSets and records are stored as arrays of values.

Best Regards,
Danijel Tkalcec
Logged
xin.chang
RTC License
***
Posts: 5


« Reply #2 on: August 05, 2017, 04:56:00 PM »

Thanks. I have updated to v8.21 to make my script get correct result by disabling AutoCollapseArrays option, and I'll consider your advice to return a dataset instead of an array to reduce memory usage.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.024 seconds with 17 queries.