I just noticed that if a variable and parameter of a where expression have the same name, there filter is ignored:
> /ip/arp/print proplist=address
Flags: H - DHCP, D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
# ADDRESS
0 C 192.168.99.2
1 HC 192.168.3.6
2 HC 192.168.3.21
3 HC 192.168.3.3
...
> /ip/arp/print proplist=address where address=1.1.1.1
> :global addr 1.1.1.1
> /ip/arp/print proplist=address where address=$addr
> :global address 1.1.1.1
> /ip/arp/print proplist=address where address=$address
Flags: H - DHCP, D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
# ADDRESS
0 C 192.168.99.2
1 HC 192.168.3.6
2 HC 192.168.3.21
3 HC 192.168.3.3
...
Yes, work as expected.
A basic rule is to never use variable names that are the names of in the system.
[rex@test] > /ip/arp/print proplist=address
Flags: D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
ADDRESS
0 DC 10.10.23.8
1 DC 10.10.23.11
2 DC 10.10.23.1
3 DC 10.10.23.10
4 DC 10.10.23.2
[rex@test] > /ip/arp/print proplist=address where address=10.10.23.8
Flags: D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
ADDRESS
0 DC 10.10.23.8
[rex@test] > :global addr 10.10.23.8
[rex@test] > /ip/arp/print proplist=address where address=$addr
Flags: D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
ADDRESS
0 DC 10.10.23.8
[rex@test] > /ip/arp/print proplist=address where address=$address ; # useless, print where address is = the address itself, so print all
Flags: D - DYNAMIC; C - COMPLETE
Columns: ADDRESS
ADDRESS
0 DC 10.10.23.8
1 DC 10.10.23.11
2 DC 10.10.23.1
3 DC 10.10.23.10
4 DC 10.10.23.2
I understand that it is not documented, but I have known about it for years.
If I had time I should write the manual for “ScriptOS” myself…
Then there are other users who by dint of digging also discover new things like >[], >“”, >{}, <%% etc.
even more difficult to discover, they have to be done at random…
But yeah both “print where” and “find” acts as iterators… In the case of “print where”, you can use an as-value to suppress print’s output to “override” it with custom output per line. I think this is a good example of some real world case for the “functions in iterators”: http://forum.mikrotik.com/t/container-traefik-on-rb5009/165849/14
(which essentially colorizes log output from Traefik container using a function in a "print).
Also [:parse “/what/ever/wierd/thing/you/want to=see”] will get you an s-expression which is closer to how the script is executed. This for sure isn’t documented, but you can see it’s a stack… so function in find gets added to stack:
(
evl /ip/arp/findwhere=
$address;
$mac-address;
$interface;
$published;
$status;
$invalid;
$dhcp;
$dynamic;
$published;
$complete;
$disabled;
$comment;
$.id;
$.nextid;
$.dead;
$.about;
(evl
(evl /ifcondition=
(= $address 10.10.23.9);
do=;
(evl
(evl /putmessage=$address)
)
)
)
;5
)
And there you can see all the attributes from [find] are provided on stack.
But essentially those allow you “inject” some code into the S-expr / IL generated. But generally those can be “shorthand” for similar “built-in” syntax & generally operate on lists.
Regarding my “alas”: the syntax works but it does not do what I initially expected. It’s executed as part of the where expression and acts as an independent condition. It’s executed for every item regardless of whether prior conditions matched*. Moreover it’s a condition itself:
> /ip/address/find where [false]
> /ip/address/find where [true]
> /ip/address/find where [($address~"^192.168.1.1/")]
which IMO is wrong since the conditions of the where expression are ANDed. Thus if the prior condition was false the scripting engine should stop further evaluation right there as an optimization. So technically supplying the condition should have worked, but alas.
As per my previous examples, is not a condition, it is executed for every single value returned by find/print.
Wrong syntax, do not work, because… is wrong…
Correct syntax (find->print to… print something):
> /ip address print where [(false)]
> /ip address print where [(true)]
> /ip address print where [($address~"^192.168.1.1/")]
/ip address print where [(false)]
print nothing because… really?
/ip address print where [(true)]
print obviously all
/ip address print where [true] or /ip address print where [false]
print obviously all because [false] return nothing, without missing ( ), and with nothing to check, print all…
Why this “clarification”?
In the previous post the invalid syntax was in the lack of parentheses around true and false…
Obviously it works if the parentheses are used correctly.
I think what @Kentzo is trying to say is that a bool (true/false) return value from the should be used as part of the filter.
i.e. if [expression] evaluated to false, then the outer find should NOT include that element in outer [find]. And, logically, that would make sense.
But string “false” or “true” is actually NOT an expression itself in scripting, so yes the parentheses are what make it an expression. And expression is what you need for either /…/find or a […].