Community discussions

MikroTik App
 
User avatar
shalak
newbie
Topic Author
Posts: 44
Joined: Sat Aug 24, 2019 11:47 am

Unexpected behavior when finding by variable value

Mon Apr 29, 2024 1:34 am

I have this snippet:
{
    :put ("HARDCODED: " . [/ip firewall filter find comment="The unique comment"])
    :local comment "The unique comment"
    :put ("VIA VAR:   " . [/ip firewall filter find comment=$comment])
}
It returns:
HARDCODED: *25
VIA VAR: *43;VIA VAR: *1;VIA VAR: *2;VIA VAR: *3;VIA VAR: *4;VIA VAR: *5;VIA VAR:.... (and so on)
Why is that, why via $comment approach, I'm getting all the rules, not just the one with the comment?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12032
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 2:01 am

comment=$comment ???

Is not one "Unexpected behavior", it is always idiotic to call variables with the same name as fields, and this is true in all programming languages(*).
# code not fixed / optimized, except for the variable name
{
    :put ("HARDCODED: " . [/ip firewall filter find comment="The unique comment"])
    :local notanidioticname "The unique comment"
    :put ("VIA VAR:   " . [/ip firewall filter find comment=$notanidioticname])
}


comment=$comment
is like
"where item comment is = to the (same) item comment", and obviously is true for all items, so all items are returned.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3606
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 2:19 am

The solution is don't use the same local variable name as the attribute. See https://wiki.mikrotik.com/wiki/Manual:S ... able_names

So using $comment would be it being nil/[:nothing], and find's matcher with nil is ignore... so it returns them all. And it repeats the "VIA VAR: " multiple times is expected since that how arrays work with concatenation. See https://wiki.mikrotik.com/wiki/Manual:S ... _to_string

Edit: See @rextended's post above - same story.
 
User avatar
shalak
newbie
Topic Author
Posts: 44
Joined: Sat Aug 24, 2019 11:47 am

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 2:33 am

comment=$comment
is like
"where item comment is = to the (same) item comment", and obviously is true for all items, so all items are returned.
Thank you!

Is not one "Unexpected behavior", it is always idiotic to call variables with the same name as fields, and this is true in all programming languages(*).
Is it now?

Let's see:

Python:
the_parameter = "value"
def the_method(the_parameter):
    print(f"Value is: {the_parameter}")

the_method(the_parameter=the_parameter)
Ruby:
the_parameter = "value"
def the_method(the_parameter)
  puts "Value is: #{the_parameter}"
end

the_method(the_parameter: the_parameter)
Kotlin:
fun theMethod(theParameter: String) {
    println("Value is: $theParameter")
}

val theParameter = "value"

fun main() {
    theMethod(theParameter = theParameter)
}
C#:
using System;

class Program {
    static void Main() {
        string theParameter = "value";
        TheMethod(theParameter: theParameter);
    }

    static void TheMethod(string theParameter) {
        Console.WriteLine($"Value is: {theParameter}");
    }
}
Swift:
func theMethod(theParameter: String) {
    print("Value is: \(theParameter)")
}

let theParameter = "value"
theMethod(theParameter: theParameter)
PHP:
function theMethod($theParameter) {
    echo "Value is: $theParameter";
}

$theParameter = "value";
theMethod(theParameter: $theParameter);
Scala:
object Main extends App {
    def theMethod(theParameter: String): Unit = {
        println(s"Value is: $theParameter")
    }

    val theParameter = "value"
    theMethod(theParameter = theParameter)
}
PowerShell:
function TheMethod {
    param([string]$theParameter)
    Write-Host "Value is: $theParameter"
}

$theParameter = "value"
TheMethod -theParameter $theParameter
R:
theMethod <- function(theParameter) {
  cat("Value is:", theParameter, "\n")
}

theParameter <- "value"
theMethod(theParameter = theParameter)
Lisp:
(defun the-method (&key the-parameter)
  (format t "Value is: ~A~%" the-parameter))

(let ((the-parameter "value"))
  (the-method :the-parameter the-parameter))
Ada:
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
    the_parameter : String := "value";

    procedure The_Method (the_parameter : String) is
    begin
        Put_Line ("Value is: " & the_parameter);
    end The_Method;
begin
    The_Method (the_parameter => the_parameter);
end Main;
All seem to work just fine... But I guess, you learn something new every day 🤷
Last edited by shalak on Mon Apr 29, 2024 11:16 am, edited 1 time in total.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3606
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 5:57 am

All seem to work just fine... But I guess, you learn something new every day 🤷
LOL, Lisp and Ada examples. Now, RouterOS's logic inherits some from LUA actually, which ver 5(?) supported. I think they created the current language to be more "config centric" than a general-purpose language. All this still has to fit in 16MB flash disks...

If you think all commands are functions, the restriction makes more sense. In a routeros function, named parameters become local variables. So when [find] "function" executes, it has a local $address inside it. And same happens with user functions:
:global fn1 do={
   :return $address
}
:put [$fn1 address=1.1.1.1]
#output: 1.1.1.1
vs.
:global fn2 do={
   :local address
   :return $address
}
:put [$fn2 address=1.1.1.1]
#output:  (nothing)
 
User avatar
shalak
newbie
Topic Author
Posts: 44
Joined: Sat Aug 24, 2019 11:47 am

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 11:25 am


If you think all commands are functions, the restriction makes more sense. In a routeros function, named parameters become local variables. So when [find] "function" executes, it has a local $address inside it. And same happens with user functions:
:global fn1 do={
   :return $address
}
:put [$fn1 address=1.1.1.1]
#output: 1.1.1.1
vs.
:global fn2 do={
   :local address
   :return $address
}
:put [$fn2 address=1.1.1.1]
#output:  (nothing)
I see, thank you for the insight. I'll be extra careful in future and be aware of the scopes/overshadowing behavior - one can easily shoot themselves in the foot because of all of this.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12032
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Unexpected behavior when finding by variable value

Mon Apr 29, 2024 2:37 pm

Is it now?
(*)
idiotic != allowed
idiotic <> allowed
...

internal code for /ip add find where address=$address

internal code

(eval /ip address find
where=$address;$network;$netmask;$broadcast;$interface;$actual-interface;$invalid;$dynamic;$disabled;$comment;$.id;$.nextid;$.dead;(= $address $address);5)
(= item1 item2) is a function that return true is both item have same value.
In this case (= $address $address), so the function return true everytime for obvious reason.


internal code for /ip add find where address=$xxx

internal code

(eval /ip address find
where=$address;$network;$netmask;$broadcast;$interface;$actual-interface;$invalid;$dynamic;$disabled;$comment;$.id;$.nextid;$.dead;(= $address $xxx);5)
This time the address is really compared with $xxx that do not exist in this ambit and is searched on local (then global if not finded) variables.

Who is online

Users browsing this forum: No registered users and 10 guests