Page 1 of 2

Wrong true value of reference variable

Posted: 06 Mar 2019, 22:00
by teadrinker

Code: Select all

var := 0
for k, v in ["var"] {
   if %v%             ; %v% = var = 0
      MsgBox, % %v%   ; MsgBox should not appear
}
For me the Message Box appears with 0.

Re: Wrong true value of reference variable in array element

Posted: 06 Mar 2019, 22:55
by wolf_II
new attempt:
Try with expression syntax:

Code: Select all

var := 0
for k, v in ["var"] {
   if (%v%)             ; %v% = var = 0
      MsgBox, % %v%   ; MsgBox should not appear
}

Re: Wrong true value of reference variable in array element

Posted: 07 Mar 2019, 00:02
by teadrinker
By this way it works as expected, but the question is why it doesn't work in my examle. More simple sample:

Code: Select all

var := 0
v := "var"
if %v%
   MsgBox, % %v%
However:

Code: Select all

var := 0
v := "var"
if %v% + 0
   MsgBox, % %v%

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 00:09
by wolf_II
I think you are (the interpreter is) using legacy if. https://www.autohotkey.com/docs/commands/IfEqual.htm

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 00:11
by jeeswg
Your script works in AHK v2:

Code: Select all

var := 0
for k, v in ["var"] {
   if %v%             ; %v% = var = 0
      MsgBox(%v%)   ; MsgBox should not appear
}
Legacy if is the issue, you can add parentheses in AHK v1 as wolf_II showed, using !! also works in AHK v1.

Code: Select all

var := 0
for k, v in ["var"] {
   if !!%v%             ; %v% = var = 0
      MsgBox(%v%)   ; MsgBox should not appear
}
Admittedly, the help mentions if var, but doesn't mention if %var%, maybe it should.
Legacy if %var% is equivalent to if (var)

Code: Select all

q:: ;test legacy if
var := 1
if %var%
	MsgBox, % "y"
else
	MsgBox, % "n"

var := 0
if %var%
	MsgBox, % "y"
else
	MsgBox, % "n"
return

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 00:38
by teadrinker
I was sure that the part of legasy "if", plased before the equal sign, is an expression. It turns out, that it can't be considered as an expression, can it?

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 01:08
by wolf_II
The docs call the first parameter Var, and describe it as variable name. There is no expression mentioned.
Edit: and by Lexikos' omission-rule, no expression involved.

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 02:01
by teadrinker
But this example works as an expression:

Code: Select all

var := 0
v := "var"
if %v% + 0
   MsgBox 1
   
if %v% + 1
   MsgBox 2

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 02:10
by wolf_II
I'm not sure, the interpretation may be smth like

Code: Select all

IfEqual, %var% + 1  ; there is no variable with name "0 + 1"
    MsgBox 2
but that is obviously not the right or full explanation, over to more competent helpers like jeeswg.
Maybe "variable name was mal-formed, we silently fail."

But I am sure this is not a bug, it's the opening of a rabbit-hole.

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 02:28
by jeeswg
There's a subset of if-statements that look like legacy if-statements, and are treated as such, the others are treated as expression if-statements, the exact rules are unclear.

Code: Select all

;legacy if-statements:
if var
if %var%
if a = b ;treated as: if (a = "b") [= is one of the 7 operators: = <> != < <= > >=]

;note:
if a == b ;treated as: if (a = "= b") [== is not one of the 7 operators]
if %v% + 0 is neither of the form if var nor if a op b where op is one of the 7 operators.
The 7 operators are listed here:
IfEqual / IfLess / IfGreater - Syntax & Usage | AutoHotkey
https://autohotkey.com/docs/commands/IfEqual.htm

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 07:37
by teadrinker
Thank you both for replies.
Anyway, nothing is clear. :)

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 08:02
by nnnik
An if-statement that contains an expression is differentiated from a traditional-if such as If FoundColor <> Blue by making the character after the word "if" an open-parenthesis. Although this is usually accomplished by enclosing the entire expression in parentheses, it can also be done with something like if (x > 0) and (y > 0). In addition, the open-parenthesis may be omitted entirely if the first item after the word "if" is a function call or an operator such as "not" or "!".
Your syntax is incorrect and the behavior thus undefined.

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 08:19
by lmstearn
From https://autohotkey.com/docs/Variables.htm#Operators
The == operator behaves identically to = except when either of the inputs is not a number, in which case == is always case sensitive and = is always case insensitive
The % operator of a single (or first) if argument is always a variable reference, or address. It's best illustrated this way:

Code: Select all

if MyVar = %MyVar%
    MsgBox The contents of MyVar agree with themselves!
But

Code: Select all

if %MyVar% = %MyVar%
    MsgBox This message won't appear!

Re: Wrong true value of reference variable

Posted: 07 Mar 2019, 09:17
by teadrinker
Thanks! At least now I know about this issue.

Re: Wrong true value of reference variable

Posted: 08 Mar 2019, 03:35
by Helgef
The rules of the distinction between traditional if and if expression are documented as,
if (expresssion) wrote: An if-statement that contains an expression is differentiated from a traditional-if such as If FoundColor <> Blue by making the character after the word "if" an open-parenthesis. [...] In addition, the open-parenthesis may be omitted entirely if the first item after the word "if" is a function call or an operator such as "not" or "!".
So if %var% shouldn't be traditional if, but rather if expression since the first item after the word if is an operator. That being said, it seems %% isn't consider an operator such as the others though, this should be clarified, for example something like if %var%v = 1, does traditional if. In addition, if expression page should either mention that if %var% and if (var) are functionally identical, similar to the remarks on the return expression page, if there is a reason for this, eg., backwards compatibility, if there is no reason for this behaviour, I would call it a bug (although I highly doubt this is isn't intended).

Also note,
If Statement wrote:Common cause of confusion: There are several other types of If statements, some of which look very similar to If (expression). These should be avoided in new scripts. If in doubt, it is best to always begin the expression with an open-parenthesis.
Which you can read as, this is a total mess, just put () around your if expressions and don't even bother to try to get the logic of this. That is what I did in v1, it worked.

Cheers.

Re: Wrong true value of reference variable

Posted: 08 Mar 2019, 07:33
by teadrinker
Helgef, thanks.

Re: Wrong true value of reference variable

Posted: 16 Mar 2019, 21:38
by lexikos
Helgef wrote:The rules of the distinction between traditional if and if expression are documented as, [...]
That part of the documentation shows some ways that the distinction can be made, not the rules of the distinction (feel free to improve the documentation). There is actually one fundamental rule:
Any If statement which does not match one of the usages shown above is interpreted as If (expression).
Source: Scripting Language | AutoHotkey
Helgef wrote:So if %var% shouldn't be traditional if, but rather if expression since the first item after the word if is an operator.
%var% is valid within any InputVar parameter, including the Var on the left side of legacy If statements (and the entire parameter for the simple If Var statement).

Re: Wrong true value of reference variable

Posted: 07 Apr 2019, 03:18
by Helgef
That part of the documentation shows some ways that the distinction can be made
That was clear, hence my comments, That being said....
There is actually one fundamental rule:
Even with the fundamental rule, the documentation is incomplete, or there is a bug, since

Code: Select all

if %var% { ; OTB -> if (expression)
}
behaves as

Code: Select all

if var {
}
Cheers.

Re: Wrong true value of reference variable

Posted: 08 Apr 2019, 03:02
by lexikos
The missing link is that the Expression in If Expression is a Numeric Parameter. If Var isn't implemented as a distinct type of statement, but as an If Expression where the parameter has reverted to a non-expression (like Return %var%). I probably didn't think of that when I wrote the new documentation, since If Var was already listed on the page for legacy If.

Helgef wrote:That was clear, hence my comments,
I literally contradicted you. If it was truly clear, you could have avoided writing inaccurate statements.

Re: Wrong true value of reference variable

Posted: 08 Apr 2019, 09:43
by Helgef
The documentation literally says, in the most relevant place possible, An if-statement that contains an expression is differentiated from a traditional-if [...], consequently, saying that the documentation says that The rules of the distinction between traditional if and if expression are documented as, [...] isn't making a false statement, not even in isolation. Given these rules, it is not a false statement to say that, So if %var% shouldn't be traditional if, but rather if expression since the first item after the word if is an operator. I then proceeded with That being said..., which clearly conveys that these rules are not complete(ly correct).
The missing link is...
Excellent :thumbup: .

Cheers.