Smorg Posted August 7, 2007 Share Posted August 7, 2007 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: expandcollapse popup[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... expandcollapse popup>"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. Link to comment Share on other sites More sharing options...
Archman Posted August 7, 2007 Share Posted August 7, 2007 (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 August 7, 2007 by Archman Link to comment Share on other sites More sharing options...
Smorg Posted August 7, 2007 Author Share Posted August 7, 2007 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 = 0ect..right... thats what I was trying to avoid. Thanks though, maybe i'll just do a separate include file that just has Dims. Link to comment Share on other sites More sharing options...
Archman Posted August 7, 2007 Share Posted August 7, 2007 There may be a better/cleaner way. Im still very new to AutoIt Link to comment Share on other sites More sharing options...
enaiman Posted August 7, 2007 Share Posted August 7, 2007 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 :) Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 7, 2007 Share Posted August 7, 2007 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! 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 Link to comment Share on other sites More sharing options...
Smorg Posted August 7, 2007 Author Share Posted August 7, 2007 (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 August 7, 2007 by Smorg Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 7, 2007 Share Posted August 7, 2007 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... 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 Link to comment Share on other sites More sharing options...
Smorg Posted August 7, 2007 Author Share Posted August 7, 2007 (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.gifArgh! You probably can't tell that I wasn't born yesterday from my illogical writing. 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 August 7, 2007 by Smorg Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 7, 2007 Share Posted August 7, 2007 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÷«zwwKÚú®¢×¢*.Á©í¶¯¢'lÊ{ZÅê뢻¢ç(ºWbz+zØ^zºè®Æ§v»§Ö§Ë²nëm«l¥u·²¢êìyÊ'uÉnzØZ·*.j·¨Ø^º'8^~*ì·¬¶iËm«r¢ìë¬x²È ñ/jVjYwÞ«¨µâ ¹ë,¶³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. 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 Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 7, 2007 Share Posted August 7, 2007 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! 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 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now