Page 1 of 1 1
Topic Options
#175755 - 2007-04-27 03:27 PM Variable Basics
tylan Offline
Starting to like KiXtart

Registered: 2005-11-17
Posts: 115
Loc: Johnstown, PA
I've read the kix help, and I'm still not sure when to declare a variable as local or global.

This all started because I was using @TICKS to measure my script execution time, and I couldn't get the answer. I thought that my script would have worked find with "$START = @TICKS" defined at the beginning of my script. However, it didn't work correct until I declared my variables as local using the DIM command.

Could I get a little help on "DIM for Dummies"

Top
#175757 - 2007-04-27 03:42 PM Re: Variable Basics [Re: tylan]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
Simplest rule is:

Don't declare your vars = GLOBAL
Declare as GLOBAL, and the contents of the variable are visible to all parts of your program, including other functions, and scripts in other files executed by CALL commands.

Declare via DIM, and the contents of the variable are only visible in the segment where they were defined. This DOES include other scripts that are CALLed, but not inside functions.

For example, try this:
 Code:
Global $X
Dim $Y

$X = "X-Var"
$Y = "Y-Var"
 
; Show current contents
"X=" $X ?
"Y=" $Y ?

; Call a function - throw away return value
$ = TestFunc() 

; Show contents after calling TestFunc
"X=" $X ?
"Y=" $Y ?

; Call the function, passing an argument, and store the result in $Y
$Y = TestFunc($Y)
; Show contents after calling TestFunc again
"X=" $X ?
"Y=" $Y ?

; Define the function
Function TestFunc(OPTIONAL $Arg)  
  ; Show contents of vars
  "X=" $X ?      ; this should display the GLOBAL var
  "Y=" $Y ?      ; this should display nothing
  "Arg=" $Arg ?  ; This is passed to func

  $TestFunc = "Func-Val"  ; return data from the function

EndFunction


This simple example shows the relationship of DIM and GLOBAL.

Generally, you want to DIM everything (good practice), pass arguments to functions, and declare as GLOBAL only things that every function should be able to view AND MODIFY!

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#175758 - 2007-04-27 03:47 PM Re: Variable Basics [Re: Glenn Barnas]
tylan Offline
Starting to like KiXtart

Registered: 2005-11-17
Posts: 115
Loc: Johnstown, PA
Just to verify...

$X=1 <--- That's global, right? If I don't use DIM or GLOBAL an implicitly declared variable is GLOBAL?

Top
#175760 - 2007-04-27 03:56 PM Re: Variable Basics [Re: tylan]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
right - not declaring is the same as declaring Global, but declaring Global clearly shows your intention, right? Non-declared vars are "accidental globals" - vars waiting to cause problems of Global Proportions. ;\)

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#175761 - 2007-04-27 03:59 PM Re: Variable Basics [Re: Glenn Barnas]
tylan Offline
Starting to like KiXtart

Registered: 2005-11-17
Posts: 115
Loc: Johnstown, PA
So, what's the big deal with global variables? If I don't reuse variable names, what's the problem? (Since we aren't talking face to face, I feel the need to mention that I'm not disagreeing. I'm just trying to understand this better.)
Top
#175764 - 2007-04-27 04:43 PM Re: Variable Basics [Re: tylan]
Mart Moderator Offline
KiX Supporter
*****

Registered: 2002-03-27
Posts: 4673
Loc: The Netherlands
 Originally Posted By: tylan

So, what's the big deal with global variables? If I don't reuse variable names, what's the problem?
....


There is no problem if you remember all your variables and anyone who has anything to do with the script like changing it and stuff keeps the same standards as you do. Also when you are relying on some variables to be there in a child script and a previous child script did something with the same names for the variables then you are screwed.

Usually with variables to filter screen output like $rc = open (1, “c:\somefile.txt”, 5) there is no problem.
_________________________
Mart

- Chuck Norris once sold ebay to ebay on ebay.

Top
#175765 - 2007-04-27 04:44 PM Re: Variable Basics [Re: tylan]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
The "problem" becomes apparent as:
A. Your scripts get bigger (my largest project currently exceeds 10,000 lines)
B. You create a library of script "snippets" that you reuse
C. You build a library of functions (UDFs) that you write, or get publicly.

In single, small scripts, it usually isn't an issue. Most of us, however, find that small scripts tend to grow, and employing good coding practices from the beginning makes the projects more managable. We also leverage UDF libraries, and indiscriminate globals tend to mess them up.

I actually started using the following format for my declarations:
 Code:
Dim $X, $I, $J         ; temporary vars
Dim $aFiles, $File     ; Array of file names & File enumeration var
Dim $Name              ; Real name of user
Global $DEBUG          ; flag indicating debug mode

Note how certain vars are defined together (temps), arrays and related index vars are paired, and global vars declared in ALL CAPS. (If their scope is VERY VISIBLE, the names should be too ;\) )

In functions that I write, I use a "$_name" format, and never use the "$_" format in front of a global, or in the main program module. On very large projects, or projects that will be publicly maintained, I use the Hungarian Variable Notation (google it) which defines standard ways to identify what kind of data will be held in a variable.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#175766 - 2007-04-27 05:16 PM Re: Variable Basics [Re: Glenn Barnas]
tylan Offline
Starting to like KiXtart

Registered: 2005-11-17
Posts: 115
Loc: Johnstown, PA
That's kinda where I thought you were going... Basically 'good habits'.

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?


Edited by tylan (2007-04-27 05:17 PM)

Top
#175769 - 2007-04-27 05:40 PM Re: Variable Basics [Re: tylan]
Witto Offline
MM club member
*****

Registered: 2004-09-29
Posts: 1828
Loc: Belgium
Yep
 Code:
If NOT @LOGONMODE
	Break On
Else
	Break Off
EndIf
Dim $RC
$RC=SetOption("Explicit", "On")
$RC=SetOption("NoMacrosInStrings", "On")
$RC=SetOption("NoVarsInStrings", "On")
$RC=SetOption("WrapAtEOL", "On")

Dim $a
$a = 2
If $a = 2
	Dim $b
	$b = 3
	$b ?
EndIf
; Error after this line if you delete the semicolon
;$b ?

Top
#175775 - 2007-04-27 07:31 PM Re: Variable Basics [Re: tylan]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
No - visibility is within a program "module" or zone.
The first part of your program is considered "main", and all the variables there are aware of each other.. Parts of a script kept in another file accessed via CALL (but not inside a function definition) are like family - know one another but don't always live together.

Functions are like different families - they only talk among themselves unless they are "introduced properly". When variables are passed to the function, the function recieves a copy of the value, not the variable itself. The copy of the value is then treated like family within the function, visible only between the function/endfunction boundaries. Of course, the function can send a (usually modified, but sometimes different) value back to the part of the script that called it.

Hope that clears things up a bit..

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#175778 - 2007-04-27 09:41 PM Re: Variable Basics [Re: Glenn Barnas]
Gargoyle Offline
MM club member
*****

Registered: 2004-03-09
Posts: 1597
Loc: Valley of the Sun (Arizona, US...
Relativly Speaking... \:\)
_________________________
Today is the tomorrow you worried about yesterday.

Top
#175779 - 2007-04-27 10:24 PM Re: Variable Basics [Re: Gargoyle]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
Groan!
_________________________
Actually I am a Rocket Scientist! \:D

Top
#175843 - 2007-05-01 11:01 AM Re: Variable Basics [Re: Glenn Barnas]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
 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.

Top
#175847 - 2007-05-01 11:45 AM Re: Variable Basics [Re: Richard H.]
Witto Offline
MM club member
*****

Registered: 2004-09-29
Posts: 1828
Loc: Belgium
Tricky. You should not DIM the vars you used a second time in a While/Loop or a If/EndIf.
Top
#175849 - 2007-05-01 01:19 PM Re: Variable Basics [Re: Witto]
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
 Originally Posted By: Witto
Tricky. You should not DIM the vars you used a second time in a While/Loop or a If/EndIf.


Depends.

Where it is possible you should only declare variables in the scope that they are going to be used and not in the top of the script. Most people re-use the same variable names for temporary storage or counters, and it is all too easy to accidentally overwrite a variable who's value is still required. Re-declaring the variable in the local scope avoids the problem.

Having said that, I rarely follow this good practice unless I know that there is a clash. ;\)

Top
#175851 - 2007-05-01 02:01 PM Re: Variable Basics [Re: Richard H.]
Witto Offline
MM club member
*****

Registered: 2004-09-29
Posts: 1828
Loc: Belgium
We can discuss long time about good coding practices.
I think most important to know is what you scripted yourself and how it works.
Maybe rarely I would also declare a variable in a If/EndIf. But I would avoid reuse of that same variable name outside this If/EndIf, or shift the declaration one stage higher.

Top
Page 1 of 1 1


Moderator:  Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 2220 anonymous users online.
Newest Members
Viginette, ManuvdWielNL, Sir_Barrington, batdk82, StuTheCoder
17888 Registered Users

Generated in 0.062 seconds in which 0.03 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org