Sign in to follow this  
Followers 0
jaberwacky

Global, Local variables, and Function Params

12 posts in this topic

#1 ·  Posted (edited)

If you declare a global variable then shouldn't that variable be available to a function without requiring that global variable to be passed as a param?

Likewise

If you declare a local variable then should that variable not be available to a function unless passed as a param?

These two code blocks do the same exact thing (at least for me they do):

Global $variable1 = "data"
Global $variable2 = "1234"

_function()

Func _function()
    MsgBox(0, '', $variable1)
    MsgBox(0, '', $variable2)

    Return 0
EndFunc ;==>_function

Local $variable1 = "data"
Local $variable2 = "1234"

_function()

Func _function()
    MsgBox(0, '', $variable1)
    MsgBox(0, '', $variable2)

    Return 0
EndFunc ;==>_function

In my most current script I have declared global variables so that I won't have to pass them everytime that I call a function. But the error I get is that the variables used inside the function are undeclared.

Ex:

#include <_runScenarios.au3>

Global $runCount = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "runcount", 1)
Global $uniqueID = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", _genUnique())
Global $version = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "version", '')

_runScenarios()

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; this is in it's own seperate file; if that matters
Func _runScenarios()
    If $runCount == 1 Then IniWrite(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", $uniqueID)

    _logFile("Program Has Been Started." & @CRLF & _
            "Windows Version: " & @OSVersion & @CRLF & _
            "OS Arch: " & @OSArch & @CRLF & _
            "UniqueID: " & $uniqueID & @CRLF & _
            "Version: " & $version, _
            @ScriptLineNumber, "_runScenarios", $runCount, 1)
EndFunc ;==>_RunScenarios

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Errors:

D:\Program.au3(7,15) : WARNING: $runCount: possibly used before declaration.
    If $runCount ==
    ~~~~~~~~~~~~~^
D:\Program.au3(7,103) : WARNING: $uniqueID: possibly used before declaration.
    If $runCount == 1 Then IniWrite(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", $uniqueID)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

I searched the forum, read about global and local variables. If anyone could throw me a bone I'd be very thankful.

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You included _runScenarios.au3 before you declared global variables.

The problem is relative physical position of those first four lines of code.

Likely that function is called inside _runScenarios.au3. Right?

edit: but doesn't have to to cause error anyway.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

You included _runScenarios.au3 before you declared global variables.

The problem is relative physical position of those first four lines of code.

Likely that function is called inside _runScenarios.au3. Right?

Ah ha! Yes, the function is called from with _runScenarios.au3. Thank you very much! So, I just fut those global variables in the _runScenarios.au3 and it works now!

How do we explain the first two code blocks that I posted

If you declare a local variable then should that variable not be available to a function unless passed as a param?

Local is Global when used outside a function.

Only inside a function will local create a local(to that function) variable.

---

edit: but doesn't have to to cause error anyway.

Looks more like Au3Check Warnings than AutoIt Errors to me.

OH ok, So I guess I was thinking like c/c++ even though I don't have a ton of experience with either language.

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

trancexx is right, it is an ordering issue.

The is no guarantee that $runCount will be declared or initialised before the function _runScenarios() is run which is dangerous.

If the parent script does not declare $runCount, you will have issues, this is bad practice.

AutoIt does handles scope like C++, you would want to do what you have done in C++ either.


Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Share this post


Link to post
Share on other sites

trancexx is right, it is an ordering issue.

The is no guarantee that $runCount will be declared or initialised before the function _runScenarios() is run which is dangerous.

If the parent script does not declare $runCount, you will have issues, this is bad practice.

AutoIt does handles scope like C++, you would want to do what you have done in C++ either.

OK, so declare my variables after I include the header file?

I think I need more time to experiment and read on scope.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

You could Dim the variables in the function.

#include <_runScenarios.au3>

Global $runCount = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "runcount", 1)
Global $uniqueID = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", _genUnique())
Global $version = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "version", '')

_runScenarios()

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; this is in it's own seperate file; if that matters
Func _runScenarios()
    Dim $runCount, $uniqueID, $version ; Will be Global if already declared Global, else Local
    If $runCount == 1 Then IniWrite(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", $uniqueID)

    _logFile("Program Has Been Started." & @CRLF & _
            "Windows Version: " & @OSVersion & @CRLF & _
            "OS Arch: " & @OSArch & @CRLF & _
            "UniqueID: " & $uniqueID & @CRLF & _
            "Version: " & $version, _
            @ScriptLineNumber, "_runScenarios", $runCount, 1)
EndFunc ;==>_RunScenarios

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Edited by MHz

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

You could Dim the variables in the function.

#include <_runScenarios.au3>

Global $runCount = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "runcount", 1)
Global $uniqueID = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", _genUnique())
Global $version = IniRead(@ScriptDir & "\Options and Settings.ini", "Settings", "version", '')

_runScenarios()

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; this is in it's own seperate file; if that matters
Func _runScenarios()
    Dim $runCount, $uniqueID, $version ; Will be Global if already declared Global, else Local
 If $runCount == 1 Then IniWrite(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", $uniqueID)

 _logFile("Program Has Been Started." & @CRLF & _
 "Windows Version: " & @OSVersion & @CRLF & _
 "OS Arch: " & @OSArch & @CRLF & _
 "UniqueID: " & $uniqueID & @CRLF & _
 "Version: " & $version, _
 @ScriptLineNumber, "_runScenarios", $runCount, 1)
EndFunc ;==>_RunScenarios

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Hey you know that idea that did occur to me... But, why redeclare though? Could I declare them as global static inside of the function? Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

Hey you know that idea that did occur to me... But, why redeclare though?

Perhaps it is to make your UDF more independent and anti-crash proof. If Au3Check thinks it is good then why ask?

Here is a example of your UDF (minor modification for test)

$reply = _runScenarios()
If @error Then
    MsgBox(0x40000, '_runScenarios() @error = ' & @error, $reply)
EndIf

Func _runScenarios()
    Dim $runCount, $uniqueID, $version ; Will be Global if already declared, else Local
    If Not $runCount Or Not $uniqueID Or Not $version Then
        Return SetError(1, 0, 'Dimmed variables in _runScenarios() contain no values')
    EndIf
    If $runCount = 1 Then
        IniWrite(@ScriptDir & "\Options and Settings.ini", "Settings", "ID", $uniqueID)
    EndIf
    _logFile("Program Has Been Started." & @CRLF & _
            "Windows Version: " & @OSVersion & @CRLF & _
            "OS Arch: " & @OSArch & @CRLF & _
            "UniqueID: " & $uniqueID & @CRLF & _
            "Version: " & $version, _
            @ScriptLineNumber, "_runScenarios", $runCount, 1)
EndFunc ;==>_RunScenarios

Func _logFile($1, $2, $3, $4, $5)
    Return 'Dummy function'
EndFunc

No script crash as the dimmed variables are valid. Your UDF will cause the script to crash. I would rather redeclare then have the script crash. The dimmed variables can be handled how you choose within the function, though consider using them safely.

Could I declare them as global static inside of the function?

Hiding a Global variable in an included function is not what I would recommend. Dim may have it's risk as well but you handle the risk responsibly and it will work OK.

You could also consider creating 3 parameters for the UDF. :idea:

Share this post


Link to post
Share on other sites

Like what MHz has done except I would declare Local inside the function and use params. This sets up the contract for use for the funciton.

If the function required the three vars to operate then they should be passed in and it is the responsibility of the parent (calling script) to ensure the vars are initialised. The other option is to use Global Const, I would not use static, however the same issue arises as it is in a separate file.

There is no substitution for things right.


Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

OK, I think I understand more clearly. I understand that using global variables is poor practice. So local variables only make sense inside of a function. Wait, if a function is being ran in AutoIt no other part of the program would have access to anything inside of the function anyway because only one thing can happen at a time. Right? Doesn't a function operate inside of another scope? And then when that scope is exited those variables that were in use are discarded...

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

Global vars ok when used correctly.

OK, I think I understand more clearly. I understand that using global variables is poor practice. So local variables only make sense inside of a function. Wait, if a function is being ran in AutoIt no other part of the program would have access to anything inside of the function anyway because only one thing can happen at a time. Right?

In a way yes. If vars are declared Local then yes but not because the computer can only do one thing at once.

Doesn't a function operate inside of another scope? And then when that scope is exited those variables that were in use are discarded...

Functions do not have scope, vars do. When a var is declared local within a function, when the function ends the var is 'discarded'. You can no longer 'see' or use the var, the scope of the var was only within the funciton.

Hope that is clear.


Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0