| View previous topic :: View next topic |
| Author |
Message |
ManaUser
Joined: 24 May 2007 Posts: 1121
|
Posted: Mon May 25, 2009 12:53 am Post subject: Can you check if a variable exists? |
|
|
Without creating it if not?
This is really minor, but I thought I remembered seeing something about this and now I can't find it. I'm sure the memory requirements for a few blank variables is not big deal, but I've got a script that dynamically creates quite a few variables, and I like to be able to check which ones are in use at a given moment without creating them, just for the sake of keeping the ListVars window uncluttered if nothing else. |
|
| Back to top |
|
 |
alhab Guest
|
Posted: Mon May 25, 2009 7:04 am Post subject: Re: Can you check if a variable exists? |
|
|
| ManaUser wrote: | | but I thought I remembered seeing something about this and now I can't find it |
This might be what you are looking for: VarExist() |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 1121
|
Posted: Mon May 25, 2009 8:04 am Post subject: |
|
|
So I'm not crazy. Thanks for finding that. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Mon May 25, 2009 2:40 pm Post subject: |
|
|
| Quote: | | Without creating it if not? | Absolutely not^.
Since the ByRef parameter of VarExist cannot be omitted, the only way to call it is with a variable which already exists. VarExist will return 0 if the variable either has never been allocated a block of memory, or has been allocated a block of memory but it has since been freed. For instance:
| Code: | MsgBox % varExist(var)
; Initialize the variable. No memory needs to be allocated for zero-length values.
var := ""
MsgBox % varExist(var)
; VarSetCapacity giveth memory.
VarSetCapacity(var, 64)
MsgBox % varExist(var)
; VarSetCapacity taketh memory away.
VarSetCapacity(var, 0)
MsgBox % varExist(var)
varExist(ByRef v) { ; Requires 1.0.46+
return &v = &n ? 0 : v = "" ? 2 : 1
}
| As documented, any non-dynamic reference to a variable creates the variable the moment the script starts. Using n:="var" and %n% in the above example does not change the results, since evaluating %n% in an expression causes var to be created. However, this does not apply to input variables. You may confirm by using ListVars:
| Code: | n = var
; The following is essentially a command with a single InputVar arg:
if %n% !=
MsgBox
ListVars
MsgBox %n% does not exist.
; Simple assignments are optimised by replacing the expression with an InputVar:
_ := %n%
ListVars
MsgBox %n% does not exist.
; Expression:
_ := (%n%)
ListVars
MsgBox %n% exists.
| Sometimes it is important to check for a dynamic variable without creating it, since each variable "permanently" consumes at least sizeof(Var) bytes. As of v1.0.48, that's only 28 bytes, but it can add up. Usually it is sufficient to compare it to an empty value using a Traditional-If as demonstrated above. Note however the following may not work as expected (it depends on what you expect):
| Code: | n = var
If %n%
MsgBox, For backwards-compatibility, 'If %n%' is equivalent to 'If n'.
|
^ It isn't possible to exclusively check whether a variable exists, but it is possible to check whether a non-empty, non-zero variable exists. In other words, there's no way to distinguish between a variable which doesn't exist and a variable which has no memory allocated to it - unless you count ListVars, but even that isn't fool-proof. |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 1121
|
Posted: Mon May 25, 2009 3:58 pm Post subject: |
|
|
| Thank you for this more complete explanation. And fortunately, for my purpose there's no need to distinguish empty vs. non-existent variables. |
|
| Back to top |
|
 |
MasterFocus
Joined: 08 Apr 2009 Posts: 3035 Location: Rio de Janeiro - RJ - Brasil
|
Posted: Tue May 26, 2009 1:13 pm Post subject: |
|
|
Is this function currently working?
It only returned 1 when I tested it. _________________ "Read the manual. Read it again. Search the forum.
Try something before asking. Show what you've tried."
Antonio França
My stuff: Google Profile |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 1121
|
Posted: Tue May 26, 2009 6:56 pm Post subject: |
|
|
This is what I ended up using:
| Code: | NoCreate(TestVar)
{
Global
If %TestVar% =
Return ""
Else
Return (%TestVar%)
} |
Pass it the name of a variable and it returns the value of the variable if it exists, otherwise it returns blank. Example:
| Code: | Yes = Yes
MsgBox % "Yes = " NoCreate("Yes")
MsgBox % "No = " NoCreate("No") |
|
|
| Back to top |
|
 |
MasterFocus
Joined: 08 Apr 2009 Posts: 3035 Location: Rio de Janeiro - RJ - Brasil
|
Posted: Tue May 26, 2009 10:27 pm Post subject: |
|
|
Yeah but I wonder if this (still) works.
| VarExist() wrote: | 0 indicates that the variable does not exist
1 indicates that the variable does exist and contains data
2 indicates that the variable does exist and is empty
(...)
AutoHotkey does not initialise an empty variable!
(...)
AutoHotkey does not delete an empty variable! |
 _________________ "Read the manual. Read it again. Search the forum.
Try something before asking. Show what you've tried."
Antonio França
My stuff: Google Profile |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Wed May 27, 2009 7:09 am Post subject: |
|
|
I included it in my previous post. Here are more examples - these gave the expected results (0, 0, 1, 2, 0) when I tested:
| Code: | n := "nonvar"
MsgBox % varExist(%n%)
MsgBox % varExist(notInitializedVar)
MsgBox % varExist(var:="initialized")
MsgBox % varExist(var:="")
VarSetCapacity(var, 0)
MsgBox % varExist(var)
varExist(ByRef v) { ; Requires 1.0.46+
return &v = &n ? 0 : v = "" ? 2 : 1
} | If your question is "Does varExist accurately report whether the variable exists?", the answer is no, as explained in my previous post. |
|
| Back to top |
|
 |
MasterFocus
Joined: 08 Apr 2009 Posts: 3035 Location: Rio de Janeiro - RJ - Brasil
|
Posted: Wed May 27, 2009 1:01 pm Post subject: |
|
|
| Lexikos wrote: | | expected results (0, 0, 1, 2, 0) when I tested |
Would you believe me if I told you that I simply copy-pasted the code and got 2 instead of 0 in the last one?  _________________ "Read the manual. Read it again. Search the forum.
Try something before asking. Show what you've tried."
Antonio França
My stuff: Google Profile |
|
| Back to top |
|
 |
Guest
|
Posted: Wed May 27, 2009 1:26 pm Post subject: |
|
|
| MasterFocus wrote: | | Lexikos wrote: | | expected results (0, 0, 1, 2, 0) when I tested |
Would you believe me if I told you that I simply copy-pasted the code and got 2 instead of 0 in the last one?  | I am a beliver. I also get 2 in the last place.  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7295 Location: Australia
|
Posted: Wed May 27, 2009 9:30 pm Post subject: |
|
|
Sorry, it was missing a line:
| Code: | n := "nonvar"
MsgBox % varExist(%n%)
MsgBox % varExist(notInitializedVar)
VarSetCapacity(var, 64) ; Ensure var is allocated dynamic vs permanent memory.
MsgBox % varExist(var:="initialized")
MsgBox % varExist(var:="")
VarSetCapacity(var, 0)
MsgBox % varExist(var)
varExist(ByRef v) { ; Requires 1.0.46+
return &v = &n ? 0 : v = "" ? 2 : 1
} |
| Quote: | | For performance reasons, freeing a variable whose previous capacity was between 1 and 63 might have no effect because its memory is of a permanent type. |
|
|
| Back to top |
|
 |
MasterFocus
Joined: 08 Apr 2009 Posts: 3035 Location: Rio de Janeiro - RJ - Brasil
|
Posted: Thu May 28, 2009 4:24 am Post subject: |
|
|
Thank you Lexikos for your explanation, concern and patience.
I'm currently calling VarExist() from another function which is intended to be used in simple scripts, so I don't have to worry about these specific issues concerning such things as VarSetCapacity().  _________________ "Read the manual. Read it again. Search the forum.
Try something before asking. Show what you've tried."
Antonio França
My stuff: Google Profile |
|
| Back to top |
|
 |
|