mIRC Homepage
Posted By: lindenkron Educational question - 24/11/13 01:47 AM
Why does this work
Code:
on *:TEXT:!youtube*:#: {
  if (!$2-) { goto b }
  if ($2- && $nick == %ADMIN. [ $+ [ $chan ] ] || $nick == %SUPERADMIN) { goto a }
  :a
  set %YOUTUBE. $+ $chan $2-
  $msg($chan,New youtube message has been set.)
  return
  :b
  $msg($chan,%YOUTUBE. [ $+ [ $chan ] ] $+ .)
  return
}


but this doesn't work
Code:
on *:TEXT:!youtube*:#: {
  if ($2- && $nick == %ADMIN. [ $+ [ $chan ] ] || $nick == %SUPERADMIN) { goto a }
  if (!$2-) { goto b }
  :a
  set %YOUTUBE. $+ $chan $2-
  $msg($chan,New youtube message has been set.)
  return
  :b
  $msg($chan,%YOUTUBE. [ $+ [ $chan ] ] $+ .)
  return
}


Calling me confused. Took me a while to move things around to figure out why something I found to be a perfectly fine script no matter how I looked at it, wouldn't work. Surely #2 if wouldn't fire no matter what (if condition isn't met), regardless of where it's positioned? Clearly something I'm missing here.

Thanks!
Posted By: Loki12583 Re: Educational question - 24/11/13 03:07 AM
This is precisely why the use of goto is frowned upon. Just use proper if statement control flow.

Code:
on *:text:!youtube*:#:{
  if ($2-) {
    if ($nick == %admin. [ $+ [ # ] ]) || ($nick == %superadmin) {
      set %youtube. $+ # $2-
      msg # New youtube message has been set.
    }
  }
  else {
    msg # %youtube. [ $+ [ # ] ]
  }
}
Posted By: Iire Re: Educational question - 24/11/13 04:09 AM
The main reason your second script doesn't work, assuming you copied it exactly as is, is because the "on" is not on the same line as the rest of the event definition. Additionally, the following condition:
Code:
if ($2- && $nick == %ADMIN. [ $+ [ $chan ] ] || $nick == %SUPERADMIN)
is probably not what you want. Rather then checking "if $2- is not $null/$false/0, and $nick either equals %ADMIN. [ $+ [ $chan ] ] or %SUPERADMIN", it's really checking "if both $2- is not $null/$false/0 and $nick equals %ADMIN. [ $+ [ $chan ] ], OR if $nick equals %SUPERADMIN". To ensure your conditions are interpreted correctly, you should use parentheses around conditional groups...

Code:
if ($2-) && ($nick == %ADMIN. [ $+ [ $chan ] ] || $nick == %SUPERADMIN) { }


To witness the difference easily, try entering the following commands in mIRC:

Code:
//if 0 && 1 || 2 { echo -ga $v1 : $v2 }
//if (0) && (1 || 2) { echo -ga $v1 : $v2 }


It's a good idea to mention, however, that when you're checking if something can be any of a list of things (such as how $nick can either be %ADMIN. [ $+ [ $chan ] ] or %SUPERADMIN), there are easier ways to do so -- in this case, $istok() is a good choice:

Code:
if $2- && $istok(%ADMIN. [ $+ [ $chan ] ] %SUPERADMIN,$nick,32) { }


(Type /help $istok if you aren't sure how it or the other $*tok identifiers work.)

Note here that because the above statement only contains two conditions (The $istok() is considered one that returns $true if $nick is either of the "tokens" listed), there is only one way to interpret the statement and thus parentheses aren't needed.

Anyway, back on the subject of goto... In my opinion, there are certain cases where using goto may be desirable, but this is not one of those cases... As was mentioned before, you should really just associate the commands with the conditions... In other words, why
Code:
if %x == 1 { goto a }
:a
echo -ga Ok, $(%x,0) == 1
return
when you could just as easily:
Code:
if %x == 1 { echo -ga Ok, $(%x,0) == 1 }
Posted By: lindenkron Re: Educational question - 24/11/13 04:50 AM
The quote with "on" was a type-o. It doesn't work even if typed properly.
Posted By: Iire Re: Educational question - 24/11/13 05:05 AM
Right, got it. So do you understand, now, that the basis of your script not working is the conditions used? In your first script, if $2- is $null/$false/0, the condition is met straight away and the command associated with it is reached (i.e., goto b)... If that condition fails, then the script tries the other condition. In your second script however, because of the way that condition is interpreted, $2- can be $null/$false/0 so long as $nick == %SUPERADMIN, so the script may well not reach the other condition.
Posted By: lindenkron Re: Educational question - 24/11/13 05:55 AM
Doesn't $2- mean if there's anything after $1 i.e. (!youtube something here)?

In that case only one of the conditions should be possible to trigger regardless of which is positioned at the front seing as there can't be both something after, and nothing after?

That's what's confusing me! smile Thanks!
Posted By: Iire Re: Educational question - 24/11/13 06:04 AM
You're correct, yes; $2- is indeed anything after $1

The issue is simply the way your condition is constructed.
Code:
if ($2- && $nick == %ADMIN. [ $+ [ $chan ] ] || $nick == %SUPERADMIN) { goto a }
checks whether: both $2- is not $null/$false/0 and $nick == %ADMIN. [ $+ [ $chan ] ]; OR $nick == %SUPERADMIN, regardless of whether $2- is specified or not. Because of this, that condition will always be met if the person triggering the script is %SUPERADMIN.

Maybe it'll help if I list the possible ways that condition can be met:

  • if $2- is not $null/$false/0 and $nick == %ADMIN. [ $+ [ $chan ] ]
  • if $2- is not $null/$false/0 but $nick != %ADMIN. [ $+ [ $chan ] ]... but $nick DOES == %SUPERADMIN
  • if $2- is $null/$false/0, but $nick == %SUPERADMIN

In short: "if A and B... or if C", rather than "if A... and if B or C".

By using parentheses to group parts of the condition like I described earlier, the interpretation changes to:

  • if $2- is not $null/$false/0, AND $nick == either %ADMIN. [ $+ [ $chan ] ] or %SUPERADMIN

Posted By: lindenkron Re: Educational question - 24/11/13 12:27 PM
Originally Posted By: Iire

  • if $2- is $null/$false/0, but $nick == %SUPERADMIN



That's the one I can't logically wrap my head around. If there's an && in the condition, the that condition must be met? The || has nothing to do with that.
$2- && <-- must be met
&
Admin || superadmin <-- either or ?

Otherwise this is the most illogical way a condition can be build I've met so far lol. And it's worked like that everywhere else in the script so far confused
Posted By: Wims Re: Educational question - 24/11/13 02:44 PM
What is it that you don't understand?
If you don't use () accordingly to give special priority (just like math) mIRC will not (or probably won't) parse the expression the way you expect it to

if (A && B || C)
is undefined, mIRC makes the choice to guess what you mean by actually interpreting it as
if (A && B) || (C)
and in this case it doesn't matter what A and B are as long as C is fine.
it will always pair the conditions from left to right.
If you want it to be A && (B || C) you need to specify it.
Posted By: lindenkron Re: Educational question - 24/11/13 05:32 PM
Originally Posted By: Wims
What is it that you don't understand?
If you don't use () accordingly to give special priority (just like math) mIRC will not (or probably won't) parse the expression the way you expect it to

if (A && B || C)
is undefined, mIRC makes the choice to guess what you mean by actually interpreting it as
if (A && B) || (C)
and in this case it doesn't matter what A and B are as long as C is fine.
it will always pair the conditions from left to right.
If you want it to be A && (B || C) you need to specify it.


Ah all right. That's an answer I can understand. So if you're specifying multiple things you need to enclose the condition groups in brackets. I thought that was only the case in certain cases with vars or identifiers.

Thank you.
© mIRC Discussion Forums