mIRC Homepage
Posted By: krin Unexpected /var behavior. - 20/11/06 08:29 AM
*edit: mIRC version 6.2

alias /vartest {
var %somevar- [ $+ [ 1 ] ] = 1
echo var: %somevar- [ $+ [ 1 ] ]
}

Output:

var: = 1

Furthermore:

alias /vartest {
var %anothervar = 1
var %somevar- [ $+ [ 1 ] ] = $rand(1,%anothervar)
echo var: %somevar- [ $+ [ 1 ] ]
}

Output:

* Invalid format: $rand (line 3, vartest.mrc)

I know about defining multiple variables with /var (ie: /var %i = 1, %x = 2), but I can't believe this is expected behavior. I only get the error when defining a var with evaluation brackets, however.

After further examination of the problem, I noted that when using evaluation brackets (/var %somevar [ $+ [ 1 ] ]), /var no longer requires "=" to assign data to the var, instead it assigns the = as part of the var's data:

alias /vartest {
var %somevar- [ $+ [ 1 ] ] = $chr(36) $+ rand(1,%anothervar) = hi
echo var: %somevar- [ $+ [ 1 ] ] / var2: %anothervar)
}

Output:
var: = $rand(1 / var2: hi

Bug, intended, what?
Posted By: Riamus2 Re: Unexpected /var behavior. - 20/11/06 02:18 PM
This was reported here.
Posted By: Mpdreamz Re: Unexpected /var behavior. - 20/11/06 06:50 PM
I dont think this is the same as jaytea's bug as 1 will never evaluate to null.

The first alias could be written as:
Code:
alias vartest {
  var %anothervar = 1
  var %somevar- [ $+ [ 1 ] ] = $rand(1, [ %anothervar ] )
  echo var: %somevar- [ $+ [ 1 ] ]
}


set is a special command where the first word wont be evaluated so in fact you dont need evaluation brackets to begin with.
//var %x = 1 , %t $+ %x = cool | echo -a %t1
will echo = cool.
//var %x = 1 , %t $+ %x = cool $rand(1,%x) | echo -a %t1

will reproduce your same error saying invalid format $rand
because it sees ,%x) as a new variable declaration.

This can be seen as a bug in the parser however why have dynamic local variables to begin with ? seems rather pointless to me smile
Posted By: krin Re: Unexpected /var behavior. - 20/11/06 08:52 PM
I can't really see how that is the same instance except for the fact that we're both using evaluation brackets. This is not inside an identifier, so it's not that, and the brackets are not evaluating a null char (1 is never null).

But just for fun, I tried it with null and got the same result.

As for the question "why use dynamic locals," there's really no reason. But generally when I'm bored I try to make my scripts as complicated as they can possibly be (I'm sure we've all done this), and I encountered this problem while doing so.

Anyway, the bugs here are when evaluation brackets are encountered after /var, it then behaves similarly to /set (in that it does not require = to assign data), and the next bug is that it ignored the priority of $rand() by treating the comma inside it as the end of the var's string, and defined a second variable (%anothervar) instead of evaluating it inside $rand()

But yeah, I guess it might be the same bug, who knows. :x
Posted By: Riamus2 Re: Unexpected /var behavior. - 20/11/06 10:51 PM
You're right. Sorry about that. I saw the same basic idea and thought it was the same problem. Evaluation brackets with variable names can always be complicated and can produce unexpected results. I've run into similar issues in the past and have had to work around them in different ways. Often, it's better to use $+() instead... and even then, you sometimes need to include $eval with it to evaluate it correctly.

As for var's not needing the equal sign with brackets, I've noticed that too and it has been a headache for me every now and then when something isn't incrementing/decrementing/$calc-ulating/etc and I have to figure out why. I usually don't think to check that = until I've checked a lot of other things. It would be great if that were fixed so that it always accepted the first = as part of the /var syntax and not as part of the variable's data.
Posted By: DaveC Re: Unexpected /var behavior. - 20/11/06 11:39 PM
I dont think its got to do with evaluation brackets at all, its something in the nature of how /VAR is really /SET -l and infact calls SET over and over once for each variable.

The problem/bug appears to be in generating the variable name before the = , if it needs to be evaluated from parts, then the = sign is appended to the transfer of value data to the /SET command, and also there is incorrect/squewered logic in identifying the end of the value data, this might have been a simple look for the next ",%" or it might be more complexe to avoid other hidden traps we dont see becuase of the way it currently does it.


Examples below assume the follwoing...
%anothervar value is 1
alias SET { echo -a >SET $1- | set $1- }

ex simply showing how /var calls /set multiple times each with a -l option for local value
//var -s %a = 1,%b = 2
>SET -ls %a 1
* Set %a to 1
>SET -ls %b 2
* Set %b to 2

ex shows the problem as it appears
//var -s %somevar- $+ $me = $rand(1,%anothervar)
* Invalid format: $rand

ex shows the problem as it is, by stopping the evaluation of the $rand, we can see the %anothervar) is considered a variable name being set, also note the inclusion of the = sign into the first variable which is also an unwanted effect
//var -s %somevar- $+ $me = $!rand(1,%anothervar)
>SET -ls %somevar-DaveC = $rand(1
* Set %somevar-DaveC to = $rand(1
>SET -ls %anothervar)
* Set %anothervar) to

ex showing how to force the evaluation of the %anothervar first, this however doesnt fix the = sign being passed
//var -s %somevar- $+ $me = $rand(1, [ %anothervar ] )
>SET -ls %somevar-DaveC = 1
* Set %somevar-DaveC to = 1

ex accompaning the above ex to show where the "1" value was generated from
//var -s %somevar- $+ $me = $!rand(1, [ %anothervar ] )
>SET -ls %somevar-DaveC = $rand(1, 1 )
* Set %somevar-DaveC to = $rand(1, 1 )


Now all this being said, I would ask a question here as to WHY do you need DYNAMIC NAMED local vars, can you actually give an example of where one might been needed?
Posted By: RusselB Re: Unexpected /var behavior. - 21/11/06 01:45 AM
While not technically needed, I sometimes find dynamically named variables easier to work with if I'm wanting to ensure a variable coincides with other information. For example tracking the number of times a particular nick has joined a particular channel, I would probably use something like
Code:
 inc $+(%,join,.,$chan,.,$nick) 
That way I can easily reference the number of times a particular nick has joined a particular channel.

You can disregard this post...I missed the fact that you were referring to local variables, rather than variables in general, but I'm going to leave the post up, for others to be able to reference.

Posted By: jaytea Re: Unexpected /var behavior. - 21/11/06 02:20 AM
yah this has in fact been reported before, but i couldn't find the post when i tried to search.. but it's quite an old bug i've been waiting to see fixed :P and as dave said it seems to happen whenever you try to combine pieces of a variable name with $+ or $+()

to 'solve' the problem you could also enclose any variable that would otherwise be seen as a new var declaration in $() or a single pair of evaluation brackets as mentioned.. or even declare the variable with /var then change its value with /set later on, a lot of workarounds laugh still would be nice if it worked correctly though
Posted By: Mpdreamz Re: Unexpected /var behavior. - 21/11/06 10:38 AM
I think its a question of what has precedence over one another.
why will:
//var %x = 1 , %t $+ %x = $rand(1,%x) | echo -a %t1
fail and
//var %x = 1 , %t = $rand(1,%x) | echo -a %t
work
parser will tokenize (lack of better term) each %variable asignment before any identifiers are evaluated. if the 2nd token is a = sign it wil start from the 3rd else start from the 2nd.
var %x = [put this into var]
var %x [$+ %t = put this into var]

since the $+ makes the evaluated %t part of the variable assignment instead of the variable content,the variable's name is now actually var %x + evaluated %t.

which explains
//var %x $+ %t = put this into var | echo -a %x
echoing = put this into var
since its
//var %x [$+ %t = put this into var] | echo -a %x
$+ %t is null space is stripped off so "= put this into var" is assigned to %x

a more complex case:
//var %t = 1 , %x $+ %t = put this into var $r(1,%t) = hello | echo -a %x1
actually parses:
//var %t = [1] , %x [$+ %t = put this into var $r(1],%t) = [hello] | echo -a %x1

back to square one:
why does this:
//var %t = 1 , %x = $r(1,%t)
not parse as:
//var %t = [1], %x = [$r(1],%t)
because the = sign makes the parser skip over any variable arguments like $var(arg1,arg2)

To proof this consider this:
//var -s %t = 1 , %x $r(1,%t) | echo -a %x
will fail because this will parse as
//var -s %t = [1] , %x [$r(1],%t) | echo -a %x

So using dynamic local variables makes the parser ignore the = statement which is needed to ignore variable arguements.

Price we pay for a lenient parser smile
Posted By: Sat Re: Unexpected /var behavior. - 21/11/06 10:56 AM
Hmm, you already pretty much covered what I was going to say here, but allow me to recap which two (separate) parser quirks we're talking about here anyway:

1. /var assumes that if you specify an '=', it will be the second space-separated parameter of each comma-separated variable declaration. If it is present, the '=' will be removed before the whole thing is passed to /set as DaveC showed. As such, it's no surprise that the following actually works:

//var %foo = $+ bar test | echo -ag -> %foobar
-> test

2. If the second space-separated parameter to (each comma-separated variable declaration in) /var is not an '=', then mIRC will split up the rest of the line in a different way, i.e. ignoring identifier parentheses etcetera. This leads to the "$rand(1" weirdness and the often seen "* Invalid format: $anyidentifier" error.

//var %foo $foo(bar,%baz)
* Invalid format: $foo
Posted By: C45P3R Re: Unexpected /var behavior. - 21/01/07 10:34 PM
Well this works


Code:
//var %x = 1, %t [ $+  [ %x ] ] $rand(1, [ %x ] ) | echo -a %t1


And to make it a bit more interesting

Code:
//var %x = 100, %t [ $+  [ %x ] ] $rand(1, [ %x ] ) | echo -a %t1 [ $+ [ $x ] ]


laugh
© mIRC Discussion Forums