Originally Posted By: tylan
So, how long is a local variable good for? You said "Declare via DIM, and the contents of the variable are only visible in the segment where they were defined." So if you Declare via DIM within a nested IF..ENDIF the variable is gone after ENDIF?


 Originally Posted By: Glenn
No - visibility is within a program "module" or zone.


Just to clarify, because it's a bit ambiguous what Glenn's "No" is referring to.

You are correct in that the scope of a local variable is within the control structure. It can get pretty tricky though.

This script demonstrates scope in a single script, but there are three not-so-obvious points to be made:
 Code:
Break ON
$=SetOption("Explicit","ON")
 
Dim $v,$counter
$v=1
"In main scope after local declaration, $$v="+$v+@CRLF
 
If "true"
	"In 'IF' before local declaration - $$v="+$v+@CRLF
	Dim $v
	$v=2
	"In 'IF' after local declaration - $$v="+$v+@CRLF
EndIf
 
"In main scope after returning from 'IF', $$v="+$v+@CRLF
 
While ($v=1 AND $counter<10)
	"In WHILE construct $$v="+$v+" $$counter="+$counter+@CRLF
	Dim $v
	$v=3
	$counter=$counter+1
Loop
"In main scope after returning from 'WHILE', $$v="+$v+@CRLF


The results from this script are:
 Quote:
In main scope after local declaration, $v=1
In 'IF' before local declaration - $v=1
In 'IF' after local declaration - $v=2
In main scope after returning from 'IF', $v=1
In WHILE construct $v=3 $counter=
In WHILE construct $v=3 $counter=1
In WHILE construct $v=3 $counter=2
In WHILE construct $v=3 $counter=3
In WHILE construct $v=3 $counter=4
In WHILE construct $v=3 $counter=5
In WHILE construct $v=3 $counter=6
In WHILE construct $v=3 $counter=7
In WHILE construct $v=3 $counter=8
In WHILE construct $v=3 $counter=9
In main scope after returning from 'WHILE', $v=1


As you can see, the value of $v in the main scope ($v=1) if unaffected by the declarations in the control structure.

The three important things to note are:
  1. In the IF construct, the parent declaration of $V is visible until the local DIM in encountered in the script.
  2. The WHILE conditional part uses the variables from the parent scope, *not* the variables which are declared within the construct.
  3. There is a bit of KiXtart magic which ensures that the DIM in the WHILE loop is only actioned once, [b]when the construct is entered[/d]. Contrast this to the IF conditional, where the local declaration is actioned when it is encountered in the code. This is subtly different behaviour that could catch you out.


The scoping problem means that it is tricky to conditionally create a local variable, i.e. this won't work:
 Code:
If Not IsDeclared($v)
   Dim $v
EndIf


However, there is a rather surprising way around it:
 Code:
$=Iif(IsDeclared($v),0,Execute("Dim $$v"))


Why is it surprising? Well, I would have expected "Execute()" to be a seperate scope, but it clearly isn't.