Sign in to follow this  
Followers 0
EdDyreen

Global, Local, Inheritance of variables

17 posts in this topic

#1 ·  Posted (edited)

I'm having some serious problems with the concept of inheritance of variables

Local $var = 'hello'
MsgBox( 0, '', '$var=' &$var )
testing()
MsgBox( 0, '', '$var=' &$var )
MsgBox( 0, '', 'endoftest' )
Exit

Func testing()
    Global $var = 'there'
    testing2()
EndFunc

Func testing2()
    MsgBox( 0, '', '$var=' &$var )
EndFunc

$var=hello
$var=there
$var=there
endoftest

Local $var = 'hello'
MsgBox( 0, '', '$var=' &$var )
testing()
MsgBox( 0, '', '$var=' &$var )
MsgBox( 0, '', 'endoftest' )
Exit

Func testing()
Local $var = 'there'
testing2()
EndFunc

Func testing2()
MsgBox( 0, '', '$var=' &$var )
EndFunc

$var=hello
$var=hello
$var=hello
endoftest

What I would like to see is:

$var=hello
$var=there
$var=hello
endoftest

I do not like to use arguments as a work around, but I might have to,

I'm not sure but I have a feeling autoIT does not know about the concept inheritance ?

Any help is greatly appreciated.

Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I don't know what "inheritance" you are talking about. What your test scripts demonstrate is scoping. If you read the help it suggests avoiding local and global vars with the same names if possible. That's why in UDFs you see those little prefixes on the variable names.

If you use Global inside a function to make a global when you already have a variable of that name defined in that scope, it's going to be bumped. See the help for scope search order with variable name clashes.

Inheritance is an OOP mechanism. A totally different animal.

Edited by MilesAhead

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

There's really no such thing as a Local variable that is created outside of a function.

Your initial Local declaration is treated as a global and accessible from within called functions.

Local $var = 'hello' ; really a global
MsgBox( 0, '', '$var=' & $var )
testing()
MsgBox( 0, '', '$var=' & $var )

Func testing()
    $var = "goodbye" ; updating external global
    Local $var = "greetings" ; creating new local variable, temporarily replacing global
    MsgBox( 0, '', '$var=' & $var )
EndFunc
Edited by Spiff59

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I was thinking about something like

set $var = 1
setlocal
   set $var = 2
   setlocal
      $var = 2
   endlocal
   $var = 2
endlocal
$var = 1

I see no other way than useing a stack to make variables persist through functions

Global $stack[1]
Global $var = 'hello'
MsgBox( 0, '', '$var=' &$var )
testing()
MsgBox( 0, '', '$var=' &$var )
MsgBox( 0, '', 'endoftest' )
Exit

Func testing()
ReDim $stack[ UBound( $stack ) + 1 ]
$stack[ UBound( $stack ) - 1 ] = $var
Global $var
$var = 'there'
testing2()
$var = $stack[ UBound( $stack ) - 1 ]
ReDim $stack[ UBound( $stack ) - 1 ]
EndFunc

Func testing2()
ReDim $stack[ UBound( $stack ) + 1 ]
$stack[ UBound( $stack ) - 1 ] = $var
Global $var
MsgBox( 0, '', '$var=' &$var )
$var = $stack[ UBound( $stack ) - 1 ]
ReDim $stack[ UBound( $stack ) - 1 ]
EndFunc
Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites

I would pass all variables I need in a function as parameters.

1 person likes this

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I understand 'water', there are subtile differences that make me not want to do that

- I want to be able to acces $var at any time from within any function, so all functions would require the parameter.

- I sometimes may want to change $var and return another variable ( without having to resort to arrays ).

I can simplify the stack method by using 2 more functions like

Global $stack[1]
Global $var = 'hello'
MsgBox( 0, '', '$var=' &$var )
testing()
MsgBox( 0, '', '$var=' &$var )
MsgBox( 0, '', 'endoftest' )
Exit

Func setLocal_( $setLocal )
    ReDim $stack[ UBound( $stack ) + 1 ]
    $stack[ UBound( $stack ) - 1 ] = Eval( $setLocal )
EndFunc

Func endLocal_( $endLocal )
    Assign ( $endLocal, $stack[ UBound( $stack ) - 1 ] , 2 )
    ReDim $stack[ UBound( $stack ) - 1 ]
EndFunc

Func testing()
    setLocal_( 'var' )

    $var = 'there'
    testing2()

    endLocal_( 'var' )
EndFunc

Func testing2()
    setLocal_( 'var' )

    MsgBox( 0, '', '$var=' &$var )

    endLocal_( 'var' )
EndFunc

It's ugly, but it works ;)

Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites

Passing a var ByRef allow changing its value outside the called function.

Else and if, definitely, there is a real, absolute, need to make a given variable global, then make it global*.

;)

* but is that necessary?


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Ed,

You may be over complicating this. You have four options

1 - use byref

2 - use "global" definition inside of function

3 - use unique variable name declared "local" outside of any function (makes it "global" in scope)

4 - use a parameter

While I think using the same variable name across multiple scopes is a poor programming technique, the following code demonstrates this using a function parameter

;
;
local $var = 10
consolewrite('$var declared outside of any function (scope = script) = ' & $var & @lf)
consolewrite('$var returned from function (scope = function)         = ' & _func01() & @lf)
consolewrite('$var declared outside of any function (scope = script) = ' & $var & @lf)
func _func01()
consolewrite('$var in func01 b/4 local definition (scope = script)   = ' & $var & @lf)
local $var = 05
consolewrite('$var in func01 aft local definition (scope = function) = ' & $var & @lf)
return $var
endfunc

Good Luck,

Kylomas

Edit : error in code fixed - this is not a "function parm" but demonstrates the principle.

Edit2: code example using a function parameter

;
;
local $var = 10
consolewrite('$var declared outside of any function (scope = script) = ' & $var & @lf)
consolewrite('$var returned from function (scope = function)         = ' & _func01(5) & @lf)
consolewrite('$var declared outside of any function (scope = script) = ' & $var & @lf)
func _func01($str)
 consolewrite('$var in func01 b/4 local definition (scope = script)   = ' & $var & @lf)
 local $var = $str
 consolewrite('$var in func01 aft local definition (scope = function) = ' & $var & @lf)
 return $var
endfunc
Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

If you need this strange scoping behaviour, then you are doing something wrong. A clean scoping schema only uses

- global scope

- namespace scope (use a prefix in AutoIt)

- module/file scope (AutoIt: emulate with a namespace, prefix)

- block scope (limited in AutoIt: no classes, no nested blocks, only functions as blocks)

If you want to build object-like behaviour, then you should use a ByRef-parameter with an array or a dictionary object ;)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

I use an array that keeps track of functions, I also use a variable that can be switched on and off, when switched on, all nested functions inherit this value, but when the function that made the switch is left the previous value is taken.

$array = null
$varry = null
call function1
$array = null
$varry = null

function1
  set $array = $array, function1
  $array = function1
  $varry = null
  call function2
  $array = function1
  $varry = null
endfunc

function2
  set $array = $array, function2
  $array = function1, function2
  $varry = null
  set $varry = function2
  call function3
  $array = function1, function2
  $varry = function2
endfunc

function3
  set $array = $array, function3
  $array = function1, function2, function3
  $varry = function2
endfunc

@ProgAndy, where can I find some in depth information on

- namespace scope (use a prefix in AutoIt)

- module/file scope (AutoIt: emulate with a namespace, prefix)

- block scope (limited in AutoIt: no classes, no nested blocks, only functions as blocks)

Thanks for your time ;)

Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites

@ProgAndy, where can I find some in depth information on

- namespace scope (use a prefix in AutoIt)

- module/file scope (AutoIt: emulate with a namespace, prefix)

- block scope (limited in AutoIt: no classes, no nested blocks, only functions as blocks)

Here? http://en.wikipedia.org/wiki/Scope_%28computer_science%29

A namespace in its simplest form can also be seen as an extension of the variable name. This can be represented with a prefix like $WINAPI_... Since there is no way to declare variables as private, this is covered with another naming rule (prefix the name with an underscore: $_WINAPI_...)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

It is now clear to me, this behavior is not default nor can it be easily simulated,

the only way I see possible to simulate this behavior ( value is visible to children but not to parents ) is by using a stack.

Thanks for making me understand, ;)

Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites

Ed,

Just curious, why do you think that you need to mimic oop behavior?

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I am exploring a debugging mechanism that could work for autoIT,

1 the program terminates succesfully

2 the program crashes

_1 All relevant information about the crash is shown onscreen for later debugging

___-An array containing a list of all nested functions called

___-The errorcode + errortext if any

3 the program hangs and has to be terminated manually

2-3

_1 the debugger is switched on before the misbehavior occurs

_2 all relevant information is shown onscreen

___-enters 'this' function

___-relevant variable contents

___-leaves 'this' function

Edited by EdDyreen

• Any number images • Images of any size • Any number of URLs • Any number of lines

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

While the basic idea is valuable, AutoIt doesn't bend easily to such exhumation.

I'm just giving my opinion: a much robust way to code routinely serious programs is to properly handle errors at the moment they occur (such as a file locked by another process, I/O error, any unexpected error cause). All "internal" errors (like the classical index of array out of bound) are not errors in my view, but programming mistakes.

Instead of making your code massively complicated and harder to maintain by using "where did I goof in fact?" post-mortem technique, place your focus in checking invariants. I almost never saw any use of _Assert in code published here, but this is a much safer/cleaner way to explicitely check subtle conditions you have doubts on hard-to-chew logic. Once you get confidence that your code is correct (it doesn't seem like, but "correct" is a very strong word in algorithmics), it's very easy to comment out all _Assert lines (edit: or comment out _DebugStartup). Note that this still doesn't prove your code correct: that would require formal methods that are even one (huge) step higher in abstraction.

EDIT: btw, there is a good visual debugger in the example scripts.

Hope you don't mind a diverging opinion!

Edited by jchd
2 people like this

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

Mmm. Sounds very similar in behavior to what my Debug_Timer() thingy is doing.

Anyway ...

Func MyFunction ( parm1, parm2, ... )

    If $gDEBUG = True then
        if parm1 = ... then ...
        assert ... (erm ... ) something
    endif

;; main function code

EndFunc
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

Error checking should be part of every script you use in production. Check the return value or @error after every function call to be sure that you can savely process the next statement.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

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