Sign in to follow this  
Followers 0
KAX

persistent variables in functions ?

16 posts in this topic

Hello to the AutoIt experts.

Is it possible to define persistent variables inside a function?

The variable should keep its value for following function calls (similar C static vars).

Example:

Func DoIt()

Dim $count = 0

$count += 1

...

EndFunc

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hello to the AutoIt experts.

Is it possible to define persistent variables inside a function?

The variable should keep its value for following function calls (similar C static vars).

Example:

Func DoIt()

Dim $count = 0

$count += 1

...

EndFunc

Constants are declared with the keyword Const.

:wacko:

Hmm... didn't think to check that a Const variable would remain in Global context when declared in a function. Have to test that... but it should work:

Global Const $FuncTime = @Hour & @Min

I wonder what happens when you run that function a second time though...

:D

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Welcome,

Use Global $variable.

A Global variable is seen by the whole script and is not destroyed if used within a function.

Edit:

Or stated more correct...is not destroyed when exiting a function. :D

Edited by MHz

Share this post


Link to post
Share on other sites

Welcome,

Use Global $variable.

A Global variable is seen by the whole script and is not destroyed if used within a function.

Edit:

Or stated more correct...is not destroyed when exiting a function. :D

You are right, global will work. But when the program grows and grows you have to be very sure which global to use. In other words : global namespace pollution.

Thank you.

Share this post


Link to post
Share on other sites

I actually like to Global everything. And when my script is done, i might change it back to Dim's or Constants. Is this a bad thing to do?

Share this post


Link to post
Share on other sites

I actually like to Global everything. And when my script is done, i might change it back to Dim's or Constants. Is this a bad thing to do?

On a small script, you maybe able to get away with that plan. But once you create a script that goes into hundreds or especially thousands of lines of code, then that would turn into a major disaster indeed. Number of Global varaibles does tend to increase with more lines of code, and does become somewhat alot to manage after awhile. That can become the so-called "Global variable pollution" problems that KAX tends to relate to.

I could not survive without Local variables in Functions to help prevent accidental Global variable destruction. :D

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Its funny when that happens, or can also be very annoying. Because you really have no idea what's going on. :D

I often have this problem when calling $x a global variable and then calling it in for loops :wacko: (For $x = )

Edited by Manadar

Share this post


Link to post
Share on other sites

I'm kind of using a rule of thumb now...

I usually keep a const region at the top of the script for values that will not change while the script runs, say paths, urls, username, whatever one can think of.

I also declare my global vars and global array vars in 2 separate regions at the top of the script, regardless of whether or not they are initialized at a later stage.

All the rest are local in the scope of functions that normally return a value which helps me in testing and debugging.

Having said all that, is anyone aware of limitation to the amount of global variables, arrays and constants a script can hold?

IVAN

Share this post


Link to post
Share on other sites

Thanks all for your replies.

It seem there is no builtin support for persistent variables.

So I decided to use naming rules to distinguish the used globals.

I. e.: %bIsInitialised_Func1

means the variable 'bIsInitialised' is reserved for function 'Func1'.

What do you thing about this?

Share this post


Link to post
Share on other sites

Thanks all for your replies.

It seem there is no builtin support for persistent variables.

So I decided to use naming rules to distinguish the used globals.

I. e.: %bIsInitialised_Func1

means the variable 'bIsInitialised' is reserved for function 'Func1'.

What do you thing about this?

Huh? :D

Whadd'ya mean by "no builtin support for persistent variables"?

Using the Global keyword is your basic answer, plus the Const keyword in special circumstances where you don't the value to be changeable. Please post a definition of what you want "persistent variables" to do. If you can, a short snippet of code demonstarting it would be very helpful.

:wacko:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I. e.: %bIsInitialised_Func1

means the variable 'bIsInitialised' is reserved for function 'Func1'.

What do you thing about this?

well, besides that % bIsInitialised_Func1 is not a variable, you can do that.

Cheers

Kurt


__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Huh? :D

Whadd'ya mean by "no builtin support for persistent variables"?

Using the Global keyword is your basic answer, plus the Const keyword in special circumstances where you don't the value to be changeable. Please post a definition of what you want "persistent variables" to do. If you can, a short snippet of code demonstarting it would be very helpful.

:wacko:

The OP is asking for a variable that is local to a function but the value stored in it persists across calls to the function. The equivalent to the static keyword in C\C++. The simplest way to think of it is access to the variable is the same as "Local" but the storage of the data in the variable is the same as "Global". An example would be:

Func Increment()
     Persistent $i = 0
     $i += 1
     Return $i      
EndFunc

MsgBox(4096, "", Increment()); Returns 1
MsgBox(4096, "", Increment()); Returns 2
; MsgBox(4096, "", $i); Error, $i is not in scope

Of course, this is not supported in AutoIt.

Edit: Fixed minor mistake.

Edited by Valik

Share this post


Link to post
Share on other sites

The OP is asking for a variable that is local to a function but the value stored in it persists across calls to the function. The equivalent to the static keyword in C\C++. The simplest way to think of it is access to the variable is the same as "Local" but the storage of the data in the variable is the same as "Global". An example would be:

Func Increment()
     Persistent $i = 0
     $i += 1
     Return $i      
EndFunc

MsgBox(4096, "", Increment()); Returns 1
MsgBox(4096, "", Increment()); Returns 2
; MsgBox(4096, "", $i); Error, $i is not in scope

Of course, this is not supported in AutoIt.

Edit: Fixed minor mistake.

My appologies for not testing this before asking, but I don't keep Windows machines around anymore, so it will have to wait for Monday...but,

Would this work?

Func Increment()
     If Not IsDeclared("Increment_i") Then Global $Increment_i = 0
     $Increment_i += 1
     Return $Increment_i        
EndFunc

MsgBox(4096, "", Increment()); Returns 1
MsgBox(4096, "", Increment()); Returns 2
; MsgBox(4096, "", $i); Error, $i is not in scope

:D


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

My appologies for not testing this before asking, but I don't keep Windows machines around anymore, so it will have to wait for Monday...but,

Would this work?

Func Increment()
     If Not IsDeclared("Increment_i") Then Global $Increment_i = 0
     $Increment_i += 1
     Return $Increment_i        
EndFunc

MsgBox(4096, "", Increment()); Returns 1
MsgBox(4096, "", Increment()); Returns 2
; MsgBox(4096, "", $i); Error, $i is not in scope

:D

First, don't ever use IsDeclared() and then use the variable directly. If you'r using IsDeclared(), you must be using Assign() and Eval(), otherwise you have a design issue. Second, using Global from inside functions is bad style.

And to answer your question, no, $Increment_i is still global. It's not possible to create static/persistent variables with AutoIt. Variables are either at the global scope where they live for the entire lifetime of the script and can be accessed from anywhere or they are local to a function, can only be accessed in that function and are destroyed when that function returns.

Share this post


Link to post
Share on other sites

Thank you Valik for your good explanations. :D

Share this post


Link to post
Share on other sites

First, don't ever use IsDeclared() and then use the variable directly. If you'r using IsDeclared(), you must be using Assign() and Eval(), otherwise you have a design issue. Second, using Global from inside functions is bad style.

And to answer your question, no, $Increment_i is still global. It's not possible to create static/persistent variables with AutoIt. Variables are either at the global scope where they live for the entire lifetime of the script and can be accessed from anywhere or they are local to a function, can only be accessed in that function and are destroyed when that function returns.

Thanks for the correction on using Assign(), I should have known that as I've used that technique to check on a $LogFile being set for the function before doing _FileWriteLog($LogFile, "etc...."). I see that the variable produced is Global and not strictly static/persistent within the function, but other than the fact that other fuctions can see the variable (maybe bad if it's a password, for example), I think it gets the same thing done. By prepending the function name (which has to be unique) to the Global variable's name you get a unique Global variable for the exclusive use of that function.

Seems that would be handy if you want to have required Global variables made available for your UDF without the script having to set it up as a precondition for using the UDF.

Func Increment()
     If Not IsDeclared("Increment_i") Then Assign(Increment_i, 0, 2); 2=Global
     $Increment_i += 1
     Return $Increment_i        
EndFunc

MsgBox(4096, "", Increment()); Returns 1
MsgBox(4096, "", Increment()); Returns 2

I guess another way to look at it would be a re-think of the function to require the script calling the function to provide a ByRef Global in the parameters. That puts the responsibility on the calling script to preserve it between calls to the function:

Global $AnyVar = 0

While 1
     Increment($AnyVar)
     MsgBox(4096, "", Increment()); Returns 1
Wend

Func Increment(ByRef $i)
     $i += 1
     Return $i
EndFunc

This has been very informative, thanks again! :D


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

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