/interface ethernet
{
:local drxByteCount [:tostr [get value-name=driver-rx-byte ether1]];
:local length [:len $drxByteCount];
:put ("drxByteCount variable is of type ".[:typeof $drxByteCount]);
:put ("drxByteCount variable is of len ".$length);
:put $drxByteCount;
:put ("first element of string with index 0 is ".[:pick $drxByteCount 0]);
:put ("last element of string with index ".($length-1)." is ".[:pick $drxByteCount ($length-1)]);
:put ("but picking from 0 to 12 gives ".[:pick $drxByteCount 0 ($length-1)]);
:put ("and picking from 0 to".$length." gives ".[:pick $drxByteCount 0 $length]);
}
this is output
[admin@TK] > system script run script3
drxByteCount variable is of type str
drxByteCount variable is of len 13
2 390 361 529
first element of string with index 0 is 2
last element of string with index 12 is 9
but picking from 0 to 12 gives 2 390 361 52
and picking from 0 to13 gives 2 390 361 529
[admin@TK] >
what am i missing here ? This looks like some kind out of bounds memory violation type error. Why is start index inclusive and end index exclusive ? This is imo very confusing to anyone who ever programed in C or C++
No, I don’t belive so, simple check by adding line
:put ("second element of string with index 1 is ".[:pick $drxByteCount 1]);
interface ethernet
{
:local drxByteCount [:tostr [get value-name=driver-rx-byte ether1]];
:local length [:len $drxByteCount];
:put ("drxByteCount variable is of type ".[:typeof $drxByteCount]);
:put ("drxByteCount variable is of len ".$length);
:put $drxByteCount;
:put ("first element of string with index 0 is ".[:pick $drxByteCount 0]);
:put ("second element of string with index 1 is ".[:pick $drxByteCount 1]);
:put ("last element of string with index ".($length-1)." is ".[:pick $drxByteCount ($length-1)]);
:put ("but picking from 0 to 12 gives ".[:pick $drxByteCount 0 ($length-1)]);
:put ("and picking from 0 to".$length." gives ".[:pick $drxByteCount 0 $length]);
}
shows
[admin@TK] > system script run script2
drxByteCount variable is of type str
drxByteCount variable is of len 13
2 747 652 611
first element of string with index 0 is 2
second element of string with index 1 is
last element of string with index 12 is 1
but picking from 0 to 12 gives 2 747 652 61
and picking from 0 to13 gives 2 747 652 611
[admin@TK] >
As far as I remember this behaviour is since the beginning of time, I agree that it is confusing at the beginning. It could be fixed, but then again it would break all existing scripts that already using pick and users that are used to current behaviour.
I simplified the output and put a second length-x in to get the correct number returned with a workaround:
{... :local drxByteCount "1 234 567 890";
{... :local length [:len $drxByteCount];
{... :put ("drxByteCount variable is of type ".[:typeof $drxByteCount]);
{... :put ("drxByteCount variable is of len ".$length);
{... :put $drxByteCount;
{... :put ("first element of string, position 0 is ".[:pick $drxByteCount 0]);
{... :put ("second element of string, position 1 is ".[:pick $drxByteCount 1]);
{... :put ("for last element of string with length ".($length)." is ".[:pick $drxByteCount ($length-2) ($length-1)]);
{... :put ("but picking first 12 character gives ".[:pick $drxByteCount 0 ($length-1)]);
{... :put ("and picking first ".$length." characters gives ".[:pick $drxByteCount 0 $length]);
drxByteCount variable is of type str
drxByteCount variable is of len 13
1 234 567 890
first element of string, position 0 is 1
second element of string, position 1 is
for last element of string with length 13 is 9
but picking first 12 character gives 1 234 567 89
and picking first 13 characters gives 1 234 567 890
I would hope however, that information about excluded upper bound in overloaded method would find her way to mikrotik scripting wiki, it could save some people lot of time while trying to debug some not working scripts.