"foreach loop" behavior change in version 7

When iterating over an array of arrays:
Up to version 7, the value we got used to be a pointer to the subarray.
Modifying some element of the subarray would persist when exiting the loop.
Starting in version 7, we get a local clone of the subarray.
Any modifications done are lost once outside the foreach loop.

I did not see any mention of such a change anywhere.
Did I miss something or am I doing something wrong ?

Here is code to illustrate the issue:

# the mother array
:global aGlobalArray ({});    

# function to add a sub-array, defined locally, to the global array
:global popData do={
    :global aGlobalArray;        
    :local subObj ({soname="soname-orig"; sodata="sodata-orig"});
    :set ($aGlobalArray->"sub-obj-1") $subObj;
    :return "OK";
}

:log info "Populate and log";
:local pop [$popData];
:foreach key,value in=$aGlobalArray do={  
    :log info ("[key:".$key."] soname:".($value->"soname")." | sodata:".($value->"sodata"));
    # result [key:sub-obj-1] soname:soname-orig | sodata:sodata-orig
}

:log info "Modify subjobj and log";
:foreach key,value in=$aGlobalArray do={  
    :set ($value->"sodata") "sodata-modified";
    # logging the data here shows it is modified    
    # Adding this line fixes the issue for v7 but is not needed in v6
    # :set ($aGlobalArray->"$key") $value;
}
:foreach key,value in=$aGlobalArray do={  
    :log info ("[key:".$key."] soname:".($value->"soname")." | sodata:".($value->"sodata"));
    # v6 result [key:sub-obj-1] soname:soname-orig | sodata:sodata-modified
    # v7 result [key:sub-obj-1] soname:soname-orig | sodata:sodata-orig
}

Thank you !

See this thread: http://forum.mikrotik.com/t/variable-reference-not-working-in-v7/168828/1

“foreach loop” behavior change in version 7

Wrong title.


It is clear that you have confused ideas.
What does the foreach loop have to do with it?

I think the :foreach is just where the change in array's from V6 to V7 shows up. Arrays are copies in V7, not "pointers". ("pass-by-value" in V7, "pass-by-reference" in V6 in CS terms)

I have come across a description of this problem many times, in particular, on the Russian-language Microtik forum, our programmers complained about the behavior of RouterOS when working with arrays. But I, by virtue of my abilities, did not understand the essence of the problem. Can one of the respected gurus explain it easier for the poor…

Easy: MikroTik has no pointers, RouterOS is not a programming language like the others. (Another example: It doesn’t even have decimal division…)
At most it has Operational Pointers (OP, like one array link shortcut) which are another thing.
What it did before in v6 was wrong, and they fixed it in v7.

There is nothing more to add.

Still, Rex, could you add… What exactly has been fixed in the work on arrays in ROS7 relative to ROS6 ?

On v6 when you assigned a value to an array variable, coming from another subvaluo on one array,
instead of copying the contents of the subpart of the array,
it overwrote the index where the data was in memory and apparently acted as a pointer,
rather than using the copied data (which was taking up and deplete memory unnecessarily) as expected.

My english is bad, i hope you understand…

Perhaps a simple example. If we take a simple array with a child array inside. The inner most value, ca, starts at “2”, and we create a new array using PART of the first one, then set subarray’s inner value to 1:

:global myarray {a=1;child={ca=2}}
:global mysubarray ($myarray->"child")
:set ($mysubarray->"ca") 1

In version 6, the “mysubarray” actually references the parent array, so by setting a value “mysubarray” the parent “myarray” value is also updated:

:put ( ($myarray->"child"->"ca") = 1)
# true

While in version 7, this changed, so the mysubarray is a copy of the original array, so updates do NOT affect myarray. So the “:set” ONLY set the one in the subarray. So the “parent” array remains using it’s original value of 2, not the updated 1.

:put ( ($myarray->"child"->"ca") = 2)
# true

Thank you very much. Now, with a simple example, everything is clear.