Big Feature: add else-if statement in console
Syntax like that:
# RouterOS
:if (<condition_1>) do={
<command>
} else-if (<condition_2>) do={
<command>
} else-if (<condition_3>) do={
<command>
} else={
<command>
};
Big Feature: add else-if statement in console
Syntax like that:
# RouterOS
:if (<condition_1>) do={
<command>
} else-if (<condition_2>) do={
<command>
} else-if (<condition_3>) do={
<command>
} else={
<command>
};
definitely +1
Should it provide
on-error={ ... }
for each do in if, if-else or the only one for the whole statement?
There is a separate :onerror handler, so I donât see any sense in this.
@teslasystems
You are right
@BartoszP
It is simple you can use
:do {} on-error={}
inside âifâ statement, However it does not require adding it besides because it will conflict with âelseâ and âelse-ifâ (if it is added in the future) or prevent you from using them.
Could you please enlighten me both how the on-error for âifâ should be used?
On the other hand, if the own âon-errorâ for each do is needed to be applied when sth goes wrong in the particular âifâ branch. If there would be the only one whole statement catching âon-errorâ then you have to collect somehow what branch triggered the error ⌠lets welcome try/catch statement
Whole idea, not only in MT scripting, of âelse-ifâ is wrong for me when there is no obligation for conditions to have anything in common. Pure:
if condition then
set of statements
else
another set of statements
endif
takes indisputably one or another execution path.
When you have multiply related or unrelated "if"s and "else if"s then there should be a statement like âswitchâ or âcase ofâ used:
case of
condition#1: set of statements for contidion#1
condition#2: set of statements for contidion#2
....
condition#N: set of statements for contidion#N
end case of
as itâs selfexplaining construction and does not relly on âsavedâ state of previous checks beeing applied to the following âelse-ifâ parts of a statement what you have to âstore in the memoryâ analyzing the code
if condition#1 then
set of statements for condition#1
else-if condition#2 then
set of statements for condition#2
...
else-if condition#N then
set of statements for condition#N
endif
really means
if condition#1 then
set of statements for TRUE(condition#1)
else-if condition#2 then
set of statements for condition#2 when FALSE(condition#1) .and. TRUE(condition#2)
...
else-if condition#N then
set of statements for condition#2 when FALSE(condition#1) .and. FALSE(condition#2) .and. ... FALSE(condition#N-1) .and. TRUE(condition#N)
endif
comparing it to much obvious
cond#1 = check#1
cond#2 = check#2
...
cond#N = check#N
case of
TRUE(condition#1) : statements for condition#1
FALSE(condition#1) .and. TRUE(condition#2) : statements for condition#2
...
FALSE(condition#1) .and. ... .and. TRUE(condition#N) : statements for condition#N
end case of
however I do open the can of worms now
There is a difference between else-if and switch-case in most languages, latter allows performing blocks for multiple conditions if condition block is not breaked (in some languages you need to state explicit continue), while else-if is explicit per condition to avoid nesting in else block. RSC even lacks break / continue statements to have proper implementation of switch-caseâŚ
Worms are getting out
What does it mean âin most languagesâ? I could agree to not agree on that.
Csomething family: use âbreakâ to break the follow-through evalutaion of the next case. For me itâs just an artifact of being planned as an assembler++ during development and it let optimize code much easier using that particular syntax.
D, Java: mimics C, uses âbreakâ
Rust: no follow-through evaluation, one statements block per case
Python: no follow-through evaluation, one statements block per case
Goldies-grandoldies COBOL, FORTRAN: one statement per case
Ada: no follow-through evaluation,
Pascal family (I should write Algol/Simula families): no-follow no follow-through
Iâm aware of these differences. Look that I intentionally assigned results of check#N to variables as evaluating a check could be a non-invariant operation. I wrote it in a quite independend syntax to not imply any language.
Iâm also aware that RSC lacks a lot of handy syntax features. Itâs not even consisten with âifâ syntax, true branch is a do={} statement but else is itâs own entity. It would be more consistent if the syntax is
if (cond) do= {
} else do={
}
I do not think there should be an else-if
. But agree is a switch
is missing, and that be preferable to to a serials of :if
. âModern languagesâ go beyond a simple switch to use âpattern matchingâ, so you a provide something to match, and set expressions (vs. C-style only a value) to test against.
Personally, supporting âgroupsâ in regular expressions would go a long way to avoid some long chains of :if
(and still helpful in some future âelse-ifâ/âswitchâ/pattern matching syntax). If you can get a regex to do the work of some chain of if else-if else, that be clear.
Also, the comparisons with âgeneral purpose languagesâ are difficult⌠RouterOS is more a âconfiguration languageâ, like Cisco TCL, one half-dozen Kubernetes languages, or even Apple boutique pkl
language where âifâ is relegated to a mere expression.
Finally, the purposed syntax ignores stuff like
:if
is still just a command (i.e. function) so the :if () do={} being followed by anything let alone multiple do= blocks violates many rules RouterOS parses things today. Meaning it be really hard to add some else-if I suspect â on top of just backwards looking.
TL;DR: â1 on âelse-ifâ statement
you can use on-error
inside if statement, as in the following example:
:if (<condition>) do={
:do {
<command>
} on-error={
<command>
};
} else={
:do {
<command>
} on-error={
<command>
};
}
But really, using a
switch
case
break
default
is best.
Yup.
Sidenote The :if is still a command (builtin function), so the on-error=
is an argument to âifâ command, just like else={}. The issue with âelse-ifâ in OP is that is NOT an argument & new commands always need a newline or semi-colon (+whitespace). And 2nd, the stack be resolved if else-if was itâs own command â why the else-if is likely harder than some new :switch
thing.
By most, I meant most modern. Ok, some languages may have different statement for multiple condition or value matching like Rust (match) but there are alot others which support multiple matching with fallthrough (as mentioned some requires explicit statement for it), like: Various C style lang including JS and TS, Swift, Kotlin, Golang⌠or scripting like Bash, TCLâŚ
Hell with this forumâŚ
Hit wrong reply button, this above post was meant to be for @BartoszP post not @Amm0âsâŚ
I canât paste same content on Reply post to @BartoszP even if I delete old because is to similarâŚ
Crap
For the whole statement it would be like this:
:local x true
:onerror errMsg {
:if ($x) do={
:put "x is true"
} else={
:put "x is false"
}
} do={
:put "Something is wrong, error: $errMsg"
}
@Moustafa :do {} on-error={}
is deprecated (thatâs what MikroTik support said) and may not work in some cases, avoid using it, use :onerror err {} do={}
instead.
And I would agree, that case or switch would be better. But it such case I would prefer Pascal-like behavior, i. e. it should stop comparing remaining conditions after first match. Or they need to add break command and let it be C-like (less preferrable).
Btw, break as a command is needed anyway! It was requested by users many times even 15 years ago and nothing was done
Where is your source that they said that?
Regardless of asking you for sources, I still use :do {} on-error={}
on a daily basis until writing this reply, and I donât have any problems, and I donât think they will remove it, because it is considered a simple and quick use of the onerror function
although they are similar, they differ in the way they work and are implemented
I see that each of them has its own method
What source? MikroTik support is the source, I said it.
As an example, snmp-get tool doesnât work with :do {} on-error={}
, only :onerror can handle it.
Anyway, itâs up to you, use it or not, I just warned.