Sign in to follow this  
Followers 0
Smorg

Assign() problem

11 posts in this topic

I use the following code to load variables from litteral variable names assigned in an ini file:

If FileExists(@ScriptDir & "\config.ini") = 0 Then
    LogEvent (1, "Cannot find " & @ScriptDir & "\config.ini")
    MsgBox(0, "Error", "Cannot find " & @ScriptDir & "\config.ini")
    Exit
EndIf

$AllVars = IniReadSection("config.ini", "oog")
For $n = 1 To $AllVars[0][0]
    Assign($AllVars[$n][0], $AllVars[$n][1])
Next

example part of the ini:

[oog]
;================================================
; Character & Account Settings
;================================================
CharMode = Single
CharAccount =
CharPassword =
CharSlot = 4
CharDifficulty = Nightmare
CharStartRunDelay = 150

;================================================
; Run Settings
;================================================
D2Path = F:\Program Files\Diablo II\
D2Executable = Diablo II.exe
D2WName = Diablo II
MultiKeys = Yes

Run_PasswordType = Random
Run_GameName = Random
Run_Interval = 10

Run_IntervalDelay = 0
Run_CreateGameDelay = 0

;================================================
; Life Managment Settings
;================================================

; Life/Mana
LifeRpotDrinkPercent = 50 
LifeFpotDrinkPercent = 30
ManaRpotDrinkPercent = 10
ManaFpotDrinkPercent = 1
ChickenLife = 15
ChickenMana = 1

; Merc
UseMerc = Yes
MercChicken = Yes
MercHealPercent = 50
MercChickenPercent = 20

; Misc
ScanDelay = 200
DrinkDelay = 1500
ChickenWaitDelay = 15000
MaxLife = 2513
MaxMana = 1039
ChickenTimeout = 1000
ChickenRetries = 3

;================================================
; Speed and Delays
;================================================
MenuMouseSpeed = 4

;================================================
; Advanced
;================================================
Parameters = -w -direct -txt
Bot_STOP_HotKey = {ESC}
Bot_PAUSE_HotKey = {PAUSE}
MMstatusURL = http://www.mmbot.net/modules/MMstatus/MMstatus.ini
MMnewsURL = http://www.mmbot.net/modules/MMstatus/MMnews.ini

Example errors...

>"F:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3" /autoit3dir "F:\Program Files\AutoIt3" /UserParams   
+>19:43:54 Starting AutoIt3Wrapper v.1.8.4
>Running AU3Check (1.54.7.0)  from:F:\Program Files\AutoIt3
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,17) : WARNING: $D2Path: possibly used before declaration.
    If Run($D2Path &
    ~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,33) : WARNING: $D2Executable: possibly used before declaration.
    If Run($D2Path & $D2Executable &
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,52) : WARNING: $Parameters: possibly used before declaration.
    If Run($D2Path & $D2Executable & " " & $Parameters)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(14,56) : WARNING: $D2_Path: possibly used before declaration.
        LogEvent(1, "Failed to launch Diablo at " & $D2_Path &
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(19,24) : WARNING: $D2WName: possibly used before declaration.
    WinWaitActive($D2WName)
    ~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(22,49) : WARNING: $MenuMouseSpeed: possibly used before declaration.
    MouseClick("Left", 100, 100, 1, $MenuMouseSpeed)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(37,24) : WARNING: $MenuStaticDelay: possibly used before declaration.
    Sleep($MenuStaticDelay)
    ~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(38,19) : WARNING: $CharAccount: possibly used before declaration.
    Send($CharAccount)
    ~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(42,20) : WARNING: $CharPassword: possibly used before declaration.
    Send($CharPassword)
    ~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(46,44) : WARNING: $CharSlot: possibly used before declaration.
    MouseClick("Left", 173 + (IsInt($CharSlot /
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(67,62) : WARNING: $GameName: possibly used before declaration.
                LogEvent(0, "Attempting to create the game " & $GameName &
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(67,74) : WARNING: $RunCount: possibly used before declaration.
                LogEvent(0, "Attempting to create the game " & $GameName & $RunCount &
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(132,53) : WARNING: $CharDifficulty: possibly used before declaration.
                    MouseClick("Left", 400, 280 + ($CharDifficulty *
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(228,37) : WARNING: $ChickenRetries: possibly used before declaration.
    For $Retries = 1 To $ChickenRetries
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(229,24) : WARNING: $KEY_ClearScreen: possibly used before declaration.
        Send($KEY_ClearScreen)
        ~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(245,46) : WARNING: $ChickenTimeout: possibly used before declaration.
        While TimerDiff($Timeout) < $ChickenTimeout
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(263,18) : WARNING: $CharMode: possibly used before declaration.
    Switch $CharMode
    ~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(341,35) : WARNING: $Bot_PAUSE_HotKey: possibly used before declaration.
HotKeySet("{" & $Bot_PAUSE_HotKey &
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(418,30) : WARNING: $D2_MultiKeys: possibly used before declaration.
    If StringInStr($D2_MultiKeys,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Confirmation.au3(17,23) : WARNING: $MMstatusURL: possibly used before declaration.
        InetGet($MMstatusURL,
        ~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Confirmation.au3(80,22) : WARNING: $MMnewsURL: possibly used before declaration.
            InetGet($MMnewsURL,
            ~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Confirmation.au3(130,16) : WARNING: $MMStatus: possibly used before declaration.
        If $MMStatus =
        ~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(55,17) : WARNING: $LoopExit: possibly used before declaration.
While $LoopExit =
~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(59,18) : WARNING: $CancelLaunch: possibly used before declaration.
If $CancelLaunch =
~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(89,34) : WARNING: $Bot_STOP_HotKey: possibly used before declaration.
HotKeySet("{" & $Bot_STOP_HotKey &
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(117,14) : WARNING: $MuliKeys: possibly used before declaration.
If $MuliKeys =
~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(150,19) : WARNING: $MultiKeys: possibly used before declaration.
                If $MultiKeys =
                ~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(165,46) : WARNING: $Run_GameName: possibly used before declaration.
        Switch CreateGame ($CharMode, $Run_GameName,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3(165,65) : WARNING: $Run_PasswordType: possibly used before declaration.
        Switch CreateGame ($CharMode, $Run_GameName, $Run_PasswordType,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,17) : ERROR: $D2Path: undeclared global variable.
    If Run($D2Path &
    ~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\Bot.au3 - 1 error(s), 29 warning(s)

Since autoit has no way of knowing that these vars are defined in advance, I get loads of variable not declared errors. These can of course be safely ignored, but it does make debugging difficult because every time i do get an error, it is buried inside hundreds of error codes that have to be sorted through. The only alternative I can think of is manually diming each (of hundreds) of user defined vars within my script, which would add lots of clutter.

Of course, once the script is compiled, these errors cannot be ignored.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

try Declaring all the variables you get errors for early in your main script even if the value isnt what it is gonna be.

I had a similar prob in a script i did, and declairing the Variables with dummy values just after the Gui code fixed it.

$D2Path = 0

$D2Executable = 0

ect..

Edited by Archman

Share this post


Link to post
Share on other sites

try Declaring all the variables you get errors for early in your main script even if the value isnt what it is gonna be.

I had a similar prob in a script i did, and declairing the Variables with dummy values just after the Gui code fixed it.

$D2Path = 0

$D2Executable = 0

ect..

right... thats what I was trying to avoid. Thanks though, maybe i'll just do a separate include file that just has Dims.

Share this post


Link to post
Share on other sites

There may be a better/cleaner way.

Im still very new to AutoIt

Share this post


Link to post
Share on other sites

You don't need to assign values to your variables at the declaration time, you just need to declare them. You will get these errors when using the variables inside functions or conditional statements.

You can simply declare them as:

Dim $D2Path, $D2Executable, $Parameters, $D2_Path, $D2WName

... and so on ...

You can declare as many variables as you wish in a single line of code.


SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Share this post


Link to post
Share on other sites

right... thats what I was trying to avoid. Thanks though, maybe i'll just do a separate include file that just has Dims.

Assign/Eval are evil... :)

Just use simple arrays to get things out of the ini and reference them in the script. Even better, if you want to reference them by name, take them from the array and create a "scripting.dictionary" object (sounds harder than it is). I put your INI file text in C:\Temp\Test.ini, and then ran this from SciTE:

#include <array.au3>

; Read INI file
$sINI = "C:\Temp\Test.ini"
Global $avINI = IniReadSection($sINI, "oog")
_ArrayDisplay($avINI, "Debug: $avINI")

; Populate scripting dictionary
Global $oDict = ObjCreate("Scripting.Dictionary")
For $n = 1 to $avINI[0][0]
    $oDict.add($avINI[$n][0], $avINI[$n][1])
Next

; Reference the dictionary
ConsoleWrite("Debug: D2Executable = " & $oDict.Item("D2Executable") & @LF)
ConsoleWrite("Debug: LifeRpotDrinkPercent = " & $oDict.Item("LifeRpotDrinkPercent") & @LF)
ConsoleWrite("Debug: Bot_PAUSE_HotKey = " & $oDict.Item("Bot_PAUSE_HotKey") & @LF)

Every time you find yourself tempted to use Assign/Eval, remember: Assign/Eval are evil! :P


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

#7 ·  Posted (edited)

Lol, evil eh? Unfortunatly Assign seems to be the only way to write to a variable whose value is contained within a string. Your method sounds cool, but does that mean i would have to rewrite the whole script to reference those object items? That sounds essentially the same as rewriting the whole script to use eval... which is obviously impossible to do since eval isn't as versitile as just using an ordinary variable name like i'm currently doing... like if you wanted to change the scope of a variable, or utilize it in a function, or return value from a function.

Edited by Smorg

Share this post


Link to post
Share on other sites

Lol, evil eh? Unfortunatly Assign seems to be the only way to write to a variable whose value is contained within a string. Your method sounds cool, but does that mean i would have to rewrite the whole script to reference those object items? That sounds essentially the same as rewriting the whole script to use eval... which is obviously impossible to do since eval isn't as versitile as just using an ordinary variable name like i'm currently doing... like if you wanted to change the scope of a variable, or utilize it in a function, or return value from a function.

This is where the logic of Assign/Eval breaks down. Those things are done at the time you code the script. Either you have to give them a literal string 'VariableName' or that is yet another variable that at some point either has to have a literal string for a name. It doesn't make any sense.

Now look at the severely broken logic of your code in the original post:

F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,17) : WARNING: $D2Path: possibly used before declaration.
    If Run($D2Path &
    ~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,33) : WARNING: $D2Executable: possibly used before declaration.
    If Run($D2Path & $D2Executable &
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
F:\Documents and Settings\Smorg\My Documents\MM Bot\SmorgBot\OOG.au3(13,52) : WARNING: $Parameters: possibly used before declaration.
    If Run($D2Path & $D2Executable & " " & $Parameters)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

Fist, "If Run(...)" is broken already, because Run() returns the PID of the process, not a status code, so this is not the way to check success/failure. Read the help file on Run() for how to keep a failure in Run() from crashing the script and getting status with Opt("RunErrorsFatal", 0), @error, and @extended.

Next, you use literal variable names for $D2Path, $D2Executable, and $Parameters without declaring them first. Now you have several ways to declare those variables and give them values. You could Dim/Global/Local declare each one, which is not as onerous as you whine about for the small number of variables concerned. But in AutoIt (unlike some other scripting languages) you can declare a variable by simply setting it's value. It's value MUST be set SOMEWHERE. You could declare it with "Dim $D2Path = 'C:\Progra~1\D2'", or just set it with "$D2Path = 'C:\Progra~1\D2'".

You mentioned changing the scope of the variable, but I don't think you get what that means, because it can't be done. A variable can be Global or Local, and there can be both Global and Local variables with the same name but different contents -- and absolutely vital concept to the use of functions (declared with Func/EndFunc). Moreover, you can have multiple instances of functions 'open' (i.e. iteration or one function calling another) where each function has different values in local variables with the same name. You can't declare a variable as Local or Global and then change it to the other, you will simply create a new variable with the same name in the other scope. The variables I used in my code, $avINI and $oDict could have been declared locally if they were inside a function, but being a bunch of settings for the whole script, it looked more reasonable that they should be Global.

More on that should wait for another topic and another rant... :)

Now, where were your values coming from? An INI file. How do you get a value from an INI file to a variable like $D2Path?

With IniReadSection().

Now you already have all the value names and data in a 2D array, but you're not satisfied, no - not you. You want to call out the data by name. That's actually fairly reasonable, and exactly what a scripting.dictionary object is for, but you didn't know that yet, so you went with the ugly, evil method of Assign(). The problem there is EVERY reference to that variable created with Assign() must now be referenced with Eval(). To eliminate the errors on the line of code above would be:

Run(Eval("D2Path") & Eval("D2Executable") & " " & Eval("Parameters"))oÝ÷ Øêò¢ç(ºWky§b¶­¡ûayض*'j¼­£*.®z+©oj¸nW¬~*쵫­¢+Ù¥´ÀÌØíÉAÑ ôÀÌØí½¥Ð¹%Ñ´ ÅÕ½ÐíÉAÑ ÅÕ½Ð줰ÀÌØíÉáÕѱôÀÌØí½¥Ð¹%Ñ´ ÅÕ½ÐíÉáÕѱÅÕ½Ð줰ÀÌØíAɵÑÉÌôÀÌØí½¥Ð¹%Ñ´ ÅÕ½ÐíAɵÑÉÌÅÕ½Ðì¤)IÕ¸ ÀÌØíÉAÑ µÀìÀÌØíÉáÕѱµÀìÅÕ½ÐìÅÕ½ÐìµÀìÀÌØíAɵÑÉÌoÝ÷ Ù8b±Æ§j[(mçhì"¶,²('üKÚ¼©ºYbazkhæj[Ú®&ë»-jëh×6Dim $D2Path = Eval("D2Path"), $D2Executable = Eval("D2Executable"), $Parameters = Eval("Parameters")
Run($D2Path & $D2Executable & " " & $Parameters)

But the scripting.dictionary does a lot of other tricks too, that Assign/Eval don't, like providing a namespace for groups of items, add, delete, sorting, returning an array of all items or values, copying the whole object with one simple command, etc.

In summary, I have only found one attempted use of Assign/Eval on this forum that didn't come straight from a fear of arrays or severely muddled thinking: Autogeneration programs like OBSFUCATE, which is a bizarre specialist's topic unto itself. Arrays are necessary and vital to good code, and scripting.dictionary is almost as useful as arrays. Assign/Eval however, are just evil... :P


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

#9 ·  Posted (edited)

Fist, "If Run(...)" is broken already, because Run() returns the PID of the process, not a status code, so this is not the way to check success/failure. Read the help file on Run() for how to keep a failure in Run() from crashing the script and getting status with Opt("RunErrorsFatal", 0), @error, and @extended.

Ah, thanks for pointing that out. Yes, I am already using Opt("RunErrorsFatal", 0)... but that does mess up this whole thing:

If Run($D2Path & $D2Executable & " " & $Parameters) = 0 Then
        LogEvent(1, "Failed to launch Diablo at " & $D2_Path & " Check your D2_Path variable in Config.au3")
        Return 0
    Else
        LogEvent(0, "D2 Loaded successfully!")
    EndIf
I try to avoid using @error whenever possible since it can get confusing within functions from getting set back to zero, and having to toggle it with SetError().

Next, you use literal variable names for $D2Path, $D2Executable, and $Parameters without declaring them first. Now you have several ways to declare those variables and give them values. You could Dim/Global/Local declare each one, which is not as onerous as you whine about for the small number of variables concerned. But in AutoIt (unlike some other scripting languages) you can declare a variable by simply setting it's value. It's value MUST be set SOMEWHERE. You could declare it with "Dim $D2Path = 'C:\Progra~1\D2'", or just set it with "$D2Path = 'C:\Progra~1\D2'".

Ah, but I thought Assign was declaring them. You say that every reference to a variable created with Assign() must be referenced with Eval(). I guess thats what my question really is... I was under the impression that Assign() could be used as a replacement for Dim/Local/Global in declaring variables... much like Call() can be used when a function's reference is contained within a string or array value. However, it doesn't seem that not using Eval() to read variables written with Assign() actually breaks the script. From what I can tell, assign does in fact effectively declare the variables in the same way that dim/local/global do, its just that the autoit wrapper cannot predict in advance that these variables are being properly assigned thus giving wrapper warnings that can be bypassed. Unless there is some sort of difference in the datatype of variables declared using assign rather than conventional means, why would I need to use eval when assign is used? And why would Assign give you flag options for declaring/assigning variables in local or global scope in this case?

It sounds like you are trying to tell me that Assign() either cannot be used to do the initial declaration of a variable, or that Assign creates a variable that has its own independent datatype which is only meant to be referenced using Eval(), and no other means. Is that correct? In that case, you are right in saying it is evil since that would severely limit the usefulness of Assign, not to mention your script being riddled with ugly Eval calls.

You mentioned changing the scope of the variable, but I don't think you get what that means, because it can't be done. A variable can be Global or Local, and there can be both Global and Local variables with the same name but different contents -- and absolutely vital concept to the use of functions (declared with Func/EndFunc). Moreover, you can have multiple instances of functions 'open' (i.e. iteration or one function calling another) where each function has different values in local variables with the same name. You can't declare a variable as Local or Global and then change it to the other, you will simply create a new variable with the same name in the other scope. The variables I used in my code, $avINI and $oDict could have been declared locally if they were inside a function, but being a bunch of settings for the whole script, it looked more reasonable that they should be Global.

More on that should wait for another topic and another rant... rolleyes.gif

Argh! You probably can't tell that I wasn't born yesterday from my illogical writing. :):P

Now you already have all the value names and data in a 2D array, but you're not satisfied, no - not you. You want to call out the data by name.

Absolutly! How crappy would that be to write a huge script like this calling every varible from $variableindex[54], $variableindex[843], etc... Sounds reminiscent of my Qbasic days back in middle school when my vars would go $A - $Z, then $AA, $AB, etc...

The idea behind this is to allow me to dynamically add, remove, or rename variables simply by putting them in the inifile, without having to go back into the script and use a huge bank of inireads, or adding each corresponding declaration manually.

But the scripting.dictionary does a lot of other tricks too, that Assign/Eval don't, like providing a namespace for groups of items, add, delete, sorting, returning an array of all items or values, copying the whole object with one simple command, etc.

In summary, I have only found one attempted use of Assign/Eval on this forum that didn't come straight from a fear of arrays or severely muddled thinking: Autogeneration programs like OBSFUCATE, which is a bizarre specialist's topic unto itself. Arrays are necessary and vital to good code, and scripting.dictionary is almost as useful as arrays.

Sweet, I'll give that a try & let you know how it works. i didn't know you could store a whole array into an object! :) Edited by Smorg

Share this post


Link to post
Share on other sites

I try to avoid using @error whenever possible since it can get confusing within functions from getting set back to zero, and having to toggle it with SetError().

It's not confusing once you see that there is only one @error macro, so if you call another function before using it, it will be changed. That just means you need to either check it right after the function, or save to a variable like $ErrorSave = @error so you can use it later.

Run($D2Path & $D2Executable & " " & $Parameters)
If @error Then
     MsgBox(16, "Error", "Error running program, @error = " & @error)
     Exit
EndIf

; Or...

Run($D2Path & $D2Executable & " " & $Parameters)
$ErrorSave = @error
$ExtendedSave = @extended
; Go do other functions...
If $ErrorSave Then
     MsgBox(16, "Error", "Error running program, @error = " & @error & "  @extended = " & @extended)
     Exit
EndIfoÝ÷ Ú«¨µà!nëH¶.@²È ¬uç%j¸§Ø^ú®¢×·¬ªê-y.±¬­«^½êò­çÞ­éÜzÚ½ªâi¹^r·µçpØ@²È k¬µ·«y÷«zww­KÚú®¢×¢*.Á©í¶¯¢'lÊ{ZÅê뢻¢ç(ºWbz+zØ^zºè®Æ§v»§Ö§Ë²nëm«l¥u·²¢êìyÊ'uÉnzØZ·*.j·¨Ø^º'­8^~*ì·¬¶iËm«r¢ì­ë¬x²È ñ/jV­jYwÞ«¨µâ ¹ë,¶­³Z¶lª¹ë-ëy©eÊ+Á«.׫¶¢Þ²È¨ØZ´,  Ü¢é]më¬yÖ¬j·©§éí~ÃoË¡Æ¥üihm©bתâÚ®&ë&¹ÈeGjYjv޺ǧiû§rبl­çÞ­éÜz+¢{ZwÂ+av¬¶¸§Ú®¶²½©n{ú®¢×¢ç©m *.­ÊyØbÉnuëayìm­ªZ­©µêí¡×ªÞ±Ê)xZ+{¦¦W¢~Ø^Ë«y©e¶Þ{eÈ­!¥¡¶¥Û!¢é]«Þmç§jëh×6For $n = 1 To $AllVars[0][0]
    ; Assign($AllVars[$n][0], $AllVars[$n][1])
    Assign($AllVars[$n][0], $AllVars[$n][1], 2)
Next

Explicit Global/Local is not generally necessary in AutoIt (it may be in some other languages). By default if you declare a variable outside of a function it will be Global, or Local if declared inside a function. Declaring a Local variable outside of a function is meaningless, because it is "local" to the scope of the whole script - which is really "global". So the only place you MUST explicitly use the keyword is when you mean to declare a Global from inside a function, because that's the only case that contradicts what would have happed by default anyway.

However, it doesn't seem that not using Eval() to read variables written with Assign() actually breaks the script. From what I can tell, assign does in fact effectively declare the variables in the same way that dim/local/global do, its just that the autoit wrapper cannot predict in advance that these variables are being properly assigned thus giving wrapper warnings that can be bypassed. Unless there is some sort of difference in the datatype of variables declared using assign rather than conventional means, why would I need to use eval when assign is used? And why would Assign give you flag options for declaring/assigning variables in local or global scope in this case?

It sounds like you are trying to tell me that Assign() either cannot be used to do the initial declaration of a variable, or that Assign creates a variable that has its own independent datatype which is only meant to be referenced using Eval(), and no other means. Is that correct? In that case, you are right in saying it is evil since that would severely limit the usefulness of Assign, not to mention your script being riddled with ugly Eval calls.

As mentioned above, it does work if you ignore errors. The people that maintain AutoIt are very good at what they do and Assign/Eval are not broken. The "evil" comes from the fact that their use always (at least to the 99th percentile) proceeds from bad practice and bad thinking, much like the occasional whining for a "GOTO" command from people who only know unstructured .bat file scripting.

Argh! You probably can't tell that I wasn't born yesterday from my illogical writing. :):P

I'm not complaining. I didn't learn about scripting.dictionary until a few months ago, and it was from this forum. That's why I hang out here, for what I learn.

(The rants are just a fun bonus!) (!)

Absolutly! How crappy would that be to write a huge script like this calling every varible from $variableindex[54], $variableindex[843], etc... Sounds reminiscent of my Qbasic days back in middle school when my vars would go $A - $Z, then $AA, $AB, etc...

The idea behind this is to allow me to dynamically add, remove, or rename variables simply by putting them in the inifile, without having to go back into the script and use a huge bank of inireads, or adding each corresponding declaration manually.

But when the script goes to use the variable, it has the name hard coded in. Like the literal string "D2Path". If you change the name of that in the INI you still have to go back and edit that string for Eval("D2Path") to work, so you didn't save anything. Lets say it changed to D3Path = C:\D3\ in the INI file. With the array or scripting.dictionary you go back and search for an item named D*Path and still get the value with either an array or dictionary reference. It can, technically be done with Assign/Eval, but is much cleaner and smarter without them.

Sweet, I'll give that a try & let you know how it works. i didn't know you could store a whole array into an object! :)

Looking forward to seeing how it comes out.

:)


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 can't edit my previous post without the forum's edit bug scrambling the whole thing... :)

My code near the top, to demo saving @error for later use, needed an edit. It should have been:

Run($D2Path & $D2Executable & " " & $Parameters)
If @error Then
     MsgBox(16, "Error", "Error running program, @error = " & @error)
     Exit
EndIf

; Or...

Run($D2Path & $D2Executable & " " & $Parameters)
$ErrorSave = @error
$ExtendedSave = @extended
; Go do other functions...
If $ErrorSave Then
     MsgBox(16, "Error", "Error running program, @error = " & $ErrorSave & "  @extended = " & $ExtendedSave)
     Exit
EndIf

I would REALLY like the forum editor to get fixed! :P


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