Page 1 of 1

Add element to associate array with custom key from variable: x {$key=$val};

Posted: Tue Oct 25, 2016 9:19 am
by warez
Hello! How i can set associate array element with key from variable?
Work code:
{
:local key "key";
:local val "value";
:local x {key=$val};
:put $x;
:put ($x->$key);
:foreach k,v in=$x do={:put ("$k=$v")}
}
output ok:
key=value
value
key=value
i want setup key in runtime :local x {$key=$val};
It's not work -> result logical expresion
output:
false

0=false

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Wed Oct 26, 2016 8:53 am
by warez
I found hard solution with global fuction:
:global Pair do={
  :global gRet "";
  :local str ":global gRet; :set gRet {\"$1\"=\"$2\"};";
  :local func [:parse $str];
  $func;
  :return $gRet;
}
Use it:
{ 
  :local key "MySuperKey";
  :local val "MyValue";
  :local x [$Pair $key $val];
  :put $x;
  :put [typeof $x];
  :put ($x->$key);
}
And have successfull out:
MySuperKey=MyValue
array
MyValue
But it's very terrible code for me and no secure for parallel tasks. May be this bug in script engine parser?
when I write
:local x {"key"="value"};
- it work fine - as named key and value of array element $x->"key"="value"

when I write
:local x {"$key"="value"}
- it work as logical expression! why? It's work as :local x {("$key"="value")} !?
this work as logical expression in ROS Ver6.37.1, 5.25 and 4.17. :-(

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Thu Oct 27, 2016 6:51 am
by Frozer
Well, no 2-dimensional arrays - it is still bearable.

This is a big flaw in the scripting language of router OS. Due to the lack of support for dynamic variables (reffer to, or create a variable with name from the value of another variable) and the possibility to define array's keys in the same manner, it ​​is not possible to create beautiful, functional and short scripts (what is important - the size of the script is limited too).

What is strange - refer to the already created keys for the arrays with variable instead key (both numeric and string) is possible. And you even can change they values, but to create - it is impossible!

I can not imagine how programmers have written ROS scripts without "foreach key, val" ("key" added only recently) :)

I wrote in the question of support, whether it is planned in the near future to add the above-mentioned features. I hope the answer will be positive :)

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Thu Oct 27, 2016 7:12 am
by Frozer
:local x {"$key"="value"}
- it work as logical expression! why? It's work as :local x {("$key"="value")} !?
this work as logical expression in ROS Ver6.37.1, 5.25 and 4.17. :-(
Nowdays, the result can be obtained such method for example:
:global GlobalScriptBuffer;
:local x ({});    
:local key "key_name";
:local val "value";
:local temp [:parse (":global GlobalScriptBuffer {\"".$key."\"=\"".$val."\"}")];
$temp;
:set x ($x , $GlobalScriptBuffer);
:put ($x->$key);

#Returns "value"
It's quite cumbersome, plus you need to keep an eye is to no other concurrently running script (or a copy of this) has not change a value in a global variable GlobalScriptBuffer - sometimes it's critical and dangerous.

So waiting for positive changes in parcer. I could be wrong, but it seems to change can be even backwards compatible ...

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Thu Oct 27, 2016 9:43 am
by warez
ThanX Frozer!
I have answer from Mikrotik support thats now it imposible!
I goto analog solution with :parse
:global Pair do={
  :global gRet "";
  :local str ":global gRet; :set gRet {\"$1\"=\"$2\"};";
  :local func [:parse $str];
  $func;
  :return $gRet;
}
and use it:
{ 
  :local key "MySuperKey";
  :local val "MyValue";
  :local x [$Pair $key $val];
  :put $x;
  :put [typeof $x];
  :put ($x->$key);
}
But the code no have secure for a parallel jobs.

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Thu Oct 27, 2016 11:09 am
by Frozer
But the code no have secure for a parallel jobs.
About what speech. A lot of code for setting the scripts in queue. A lot of code for simple operations. All this may be avoided by adding dynamic variables and posibility to define arrays key from variable's values.

So waiting for action from the developers, and continue to torment our brains :-)

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Mon Oct 31, 2016 8:07 pm
by warez
Frozer HA-HA! It's so easy! Add dynamic elements with :set command, when key doesn't exist!
{
:local key1 "MyKey1";
:local key2 "MyKey2";
:local val1 "MyValue1";
:local val2 "MyValue2";
:local a ({});
#Add dynamic elements!
:set ($a->$key1) $val1;
:set ($a->$key2) $val2;

:put $a;
:put [:len $a];
:put ($a->$key1);
:put ($a->$key2);
}
Output
MyKey1=MyValue1;MyKey2=MyValue2
2
MyValue1
MyValue2
:-)

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Mon Oct 31, 2016 11:17 pm
by warez
Great MikroTik Support! Please help with this code:
:global ggg do={
  :local x ({});
  :set ($x->$arg) $arg;
  :return $x;
}
:put [$ggg arg=1];
:put [$ggg arg=2];
:put [$ggg arg=3];
Attention output:
[admin@Work] > :put [$ggg arg=1];
1=1
[admin@Work] > :put [$ggg arg=2];
1=1;2=2
[admin@Work] > :put [$ggg arg=3];
1=1;2=2;3=3
This is bug? How x variable save between function calls!? I set it empty array: :local x ({});?
:shock:

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Tue Nov 01, 2016 2:52 am
by Frozer
Frozer HA-HA! It's so easy! Add dynamic elements with :set command, when key doesn't exist!
{
:local key1 "MyKey1";
:local key2 "MyKey2";
:local val1 "MyValue1";
:local val2 "MyValue2";
:local a ({});
#Add dynamic elements!
:set ($a->$key1) $val1;
:set ($a->$key2) $val2;
:-)
Hm... It seems so many times tried. Really works :-) Then it greatly simplifies my life. Thank you :-)

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Tue Nov 01, 2016 2:57 am
by Frozer
Great MikroTik Support! Please help with this code:
This is bug? How x variable save between function calls!? I set it empty array: :local x ({});?
:shock:
It is better to write to support@mikrotik.com, where they will do anything faster. Function feature added recently so can be really bug.

Re: Add element to associate array with custom key from variable: x {$key=$val};

Posted: Fri Jun 15, 2018 3:45 am
by alli
Frozer HA-HA! It's so easy! Add dynamic elements with :set command, when key doesn't exist!
{
:local key1 "MyKey1";
:local key2 "MyKey2";
:local val1 "MyValue1";
:local val2 "MyValue2";
:local a ({});
#Add dynamic elements!
:set ($a->$key1) $val1;
:set ($a->$key2) $val2;
:-)
Hm... It seems so many times tried. Really works :-) Then it greatly simplifies my life. Thank you :-)

This method works in this simple scenario, but as strings are pointers they won't works in complex cases, it took me hours to figure this out. Maybe this works with int variable i haven't tested it thoroughly.