Community discussions

MikroTik App
 
User avatar
merlinthemagic7
newbie
Topic Author
Posts: 47
Joined: Fri Sep 16, 2016 8:49 pm

Variable by reference documentation? (v6 BUG)

Thu Jul 28, 2022 1:43 pm

Hi,

Is it no longer possible to have a global variable update by reference in v7?
:global TestVar;
:if ($TestVar = nil) do={
	:set TestVar [:toarray ""];
	:set ($TestVar->"nbr1") [:toarray ""];
	:set ($TestVar->"nbr1"->"count") 0;
}

:local nbr1 ($TestVar->"nbr1");
:set ($nbr1->"count") (($nbr1->"count") + 1);
:put ($nbr1->"count"); #1
On v6 the global variable is updated as "count" increments, but in v7 it does not.

Is there any documentation on what has changed v6 vs. v7 when it comes to scripting? e.g. did the model shift to COW?
 
User avatar
mrz
MikroTik Support
MikroTik Support
Posts: 7038
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 2:43 pm

Works for me on v7 too.

Depends on how you are trying to run that code, if you paste it in the terminal then whole code must be in {} braces otherwise local varaible expires in next line.
 
User avatar
merlinthemagic7
newbie
Topic Author
Posts: 47
Joined: Fri Sep 16, 2016 8:49 pm

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:21 pm

Hi Mrz,

Lets make sure its apples to apples:
/system script
add name=script1 policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":global TestVar;\r\
    \n:if (\$TestVar = nil) do={\r\
    \n\t:set TestVar [:toarray \"\"];\r\
    \n\t:set (\$TestVar->\"nbr1\") [:toarray \"\"];\r\
    \n\t:set (\$TestVar->\"nbr1\"->\"count\") 0;\r\
    \n}\r\
    \n\r\
    \n:local nbr1 (\$TestVar->\"nbr1\");\r\
    \n:set (\$nbr1->\"count\") ((\$nbr1->\"count\") + 1);\r\
    \n:put (\$nbr1->\"count\"); #1\r\
    \n\r\
    \n:put (\$TestVar->\"nbr1\"->\"count\"); #0 on v7"
V6 output:
[admin@ros-v6-49-2] > /system script run script1
4
4
[admin@ros-v6-49-2] > /system script run script1
5
5
[admin@ros-v6-49-2] > /system script run script1
6
6
V7 output:
[admin@ros-v7-4] > /system script run script1
1
0
[admin@ros-v7-4] > /system script run script1
1
0
[admin@ros-v7-4] > /system script run script1
1
0
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:33 pm

"if ($TestVar = nil) do={" NIL???

v6 code

[@] > :global kkk
[@] > :put $kkk

[@] > :put [:typeof $kkk]
nothing

v7 code

[@] > :global kkk
[@] > :put $kkk

[@] > :put [:typeof $kkk]
nothing

Correct:
:if ([:typeof $TestVar] = "nothing") do={
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:37 pm

@merlinthemagic7, next time specify that the problem is when you reiterate the function, not on running it one time only....
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:41 pm

The correct behavior is on v7, the local (=discarded later) variables must not be treated as pointer, and updating local variable must not influence global variable, until is not directly wanted.

a simplified examples work identically on both v6 and v7
{
:global TestVar
:if ([:typeof $TestVar] = "nothing") do={ :set TestVar 0 }
:local nbr1 $TestVar
:set $nbr1 ($nbr1 + 1)
:put $nbr1
}
 
User avatar
merlinthemagic7
newbie
Topic Author
Posts: 47
Joined: Fri Sep 16, 2016 8:49 pm

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:44 pm

Both work.

Can someone share a code snippet where a global array is set, then an index from that array is set in a local and when the index is changed the global reflects this change.
/system/script/environment/remove [find where name="TestVar"];

:global TestVar;
:if ($TestVar = nil) do={
	:put ("NIL works");
} else={
	:put ("NIL no workie");
}

:if ([:typeof $TestVar] = "nothing") do={
	:put ("Type 'nothing' works");
} else={
	:put ("Type 'nothing' no workie");
}
 
User avatar
merlinthemagic7
newbie
Topic Author
Posts: 47
Joined: Fri Sep 16, 2016 8:49 pm

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:51 pm

The correct behavior is on v7, the local (=discarded later) variables must not be treated as pointer, and updating local variable must not influence global variable, until is not directly wanted.
Shared memory is nice, as long as there the proper locks in place.

Is there a document i can read that informs of the change away from pointers? Would be nice to know what changes have been made between V6 and V7, before settling on a design pattern?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:55 pm

:global TestVar;
:if ($TestVar = nil) do={
	:put ("NIL works");
} else={
	:put ("NIL no workie");
}
"nil" do not exist, like "str"

you can replace nil with any unexistant string and is the same

This works because is the returned string value of the typeof check
:if ([:typeof $TestVar] = "nothing") do={

test:
:put nil
:put anything
:put [:typeof [nothing]]
:put [:typeof [nil]]
:put [:typeof nothing]
:put [:typeof nil]
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 3:58 pm

What happened on the past with nested array is a bug. If is a feature, also this must on v6 increase the TestVar value, but not happen...
{
:global TestVar
:if ([:typeof $TestVar] = "nothing") do={ :set TestVar 0 }
:local nbr1 $TestVar ; # nbr1 is not a pointer, the value is copied
:set $nbr1 ($nbr1 + 1)
:put $nbr1
:put $TestVar ; # the global var is not influenced
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 4:03 pm

using your example, just removing one nested array, also this, if is a feature, must update main TestVar, but is not happening on v6 or on v7
{
:global TestVar;
:if ($TestVar = nil) do={
	:set TestVar [:toarray ""];
	:set ($TestVar->"count") 0;
}

:local nbr1 ($TestVar->"count"); # this is not one pointer, the value inside the array is copied
:set $nbr1 ($nbr1 + 1);
:put $nbr1
:put $TestVar ; # this remaining not influenced
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation?

Thu Jul 28, 2022 4:06 pm

This is the BUG on v6 and on v7 is fixed.
{
:global TestVar;
:if ($TestVar = nil) do={
	:set TestVar [:toarray ""];
	:set ($TestVar->"nbr1") [:toarray ""];
	:set ($TestVar->"nbr1"->"count") 0;
}

:local nbr1 ($TestVar->"nbr1"); # BUG on v6, instead of copy inner array, is copied the memory position
:set ($nbr1->"count") (($nbr1->"count") + 1);
:put ($nbr1->"count");
:put $TestVar; # is influenced because the presence of the BUG.
}
 
User avatar
merlinthemagic7
newbie
Topic Author
Posts: 47
Joined: Fri Sep 16, 2016 8:49 pm

Re: Variable by reference documentation?

Thu Jul 28, 2022 4:12 pm

This is the BUG on v6 and on v7 is fixed.
I believe you. Is there any document that talks about this and other changes? Where did you learn that MT considers this a bug to be fixed in V7? Like the title says, im looking for documentation.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Variable by reference documentation? (v6 BUG)

Thu Jul 28, 2022 4:19 pm

Where did you learn that MT considers this a bug to be fixed in V7? Like the title says, im looking for documentation.
There is no need to see it written when it clearly works only in extreme cases and in normality it does not happen...
I repeat: if it was intended, the behavior should have been the same in the other examples,
AND ESPECIALLY there had to be a method to copy WITHOUT necessarily creating a reference that update global variable...


"change" are listed when something is done on purpose
when a bug is fixed, can be "accidentally" fixed because is not known...

for more information contact directly support@mikrotik.com and hope than some programmers reply about this bug...
 
User avatar
mrz
MikroTik Support
MikroTik Support
Posts: 7038
Joined: Wed Feb 07, 2007 12:45 pm
Location: Latvia
Contact:

Re: Variable by reference documentation? (v6 BUG)  [SOLVED]

Thu Jul 28, 2022 6:04 pm

There is no documentation about variable referencing because RouterOS scripting does not have referencing concept. Set should perform deep copy which it apparently did not in ROSv6.

Who is online

Users browsing this forum: No registered users and 13 guests