Jump to content

Recommended Posts

Posted (edited)

Ok. I have to admit that I didn't know there's such a short alternative. Indeed, both snippets work the intended way; I missed the ContinueCase trick.

I never used ContinueCase so I misjudged it thinking that it continues checking the next Case, even if the current one is true. In other languages the command 'break' is used at the end of every 'case' statements block in order to exit the switch once a 'case' is true. Otherwise, the condition would check for the next 'case' even if the current one is true, by default.

I don't want to be an ignorant stubborn but think about the fact that it's more intuitive and straight forward to conceive the code logic with Goto than with Switch and ContinueCase. This is indeed a very good alternative but it's an alternative. And let's not forget that for every jump we want to make we have to create and call a function. Later on writing the code, for a back jump we have to rethink (and realign) the code.

We don't have to be ashamed with Goto, as it's used in the most epic language, mother of all languages: assembler (also linear) - je, jne, call, ret etc. But its awesome power is feared by the weak :(

There are cases where Switch can't help. Cases when nested functions are to be used. Can someone tell me that it's easier to follow the code flow in nested functions than in Goto codes? You have to continually go back and forth between calls and definitions of functions. Another unbeated advantage for Goto is that in many cases once you followed a few Goto jumps you don't need to know where you started from. With functions it's a bit different. You leave traces in your mind so to know to come back just in case the function continues after calling another function. And so forth, spanning on 2 to 5-6 levels...

Edited by mireazma
Posted

All due respect, but the power of goto was never in question, it was the sanity of using it when other options were available. While it's true that every control structure could be recreated with only je and jne, why go through all the pain of reinventing the wheel?

#fgpkerw4kcmnq2mns1ax7ilndopen (Q, $0); while ($l = <Q>){if ($l =~ m/^#.*/){$l =~ tr/a-z1-9#/Huh, Junketeer's Alternate Pro Ace /; print $l;}}close (Q);[code] tag ninja!

Posted

But its awesome power is feared by the weak

The Weak? :( I think thats a bit much. Were talking about extremely smart computer scientists that pushed the use of structured programming.

Posted (edited)

Ok. I have to admit that I didn't know there's such a short alternative. Indeed, both snippets work the intended way; I missed the ContinueCase trick.

I never used ContinueCase so I misjudged it thinking that it continues checking the next Case, even if the current one is true. In other languages the command 'break' is used at the end of every 'case' statements block in order to exit the switch once a 'case' is true. Otherwise, the condition would check for the next 'case' even if the current one is true, by default.

I don't want to be an ignorant stubborn but think about the fact that it's more intuitive and straight forward to conceive the code logic with Goto than with Switch and ContinueCase. This is indeed a very good alternative but it's an alternative. And let's not forget that for every jump we want to make we have to create and call a function. Later on writing the code, for a back jump we have to rethink (and realign) the code.

We don't have to be ashamed with Goto, as it's used in the most epic language, mother of all languages: assembler (also linear) - je, jne, call, ret etc. But its awesome power is feared by the weak :(

There are cases where Switch can't help. Cases when nested functions are to be used. Can someone tell me that it's easier to follow the code flow in nested functions than in Goto codes? You have to continually go back and forth between calls and definitions of functions. Another unbeated advantage for Goto is that in many cases once you followed a few Goto jumps you don't need to know where you started from. With functions it's a bit different. You leave traces in your mind so to know to come back just in case the function continues after calling another function. And so forth, spanning on 2 to 5-6 levels...

To add on from what Fulano said, from experience gotos lead to the dark side. They are powerful and great however their use always leads to always lead to maintenance issues. Their use is a sign of poor programming, laziness or a lack of understanding of the language. If you know better there is no excuses for using them.

I have seen first had ‘smart’ people use them instead if catch statements because they are ‘clean, simple and quicker’. This lead to a three fold blow out in development time because they were too stupid and lazy to do the right thing even after they were warned. I could go on.

I believe they are like drugs, they ultimate lead to no good. Good to see they are removed from the language.

Edited by bo8ster

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]

Posted (edited)

Can someone tell me that it's easier to follow the code flow in nested functions than in Goto codes?

Have you tried Object Oriented Programming yet?

At some point, those smart programmers realized the limitations of procedural programming, like long recompilation times or difficulty in code changing/maintenance for large projects, so they created a new programming paradigm which broke up the code into separate objects. Among other things, this allowed for easier maintenance because, with good design, you are able to minimize the amount of code you need to change when you make alterations to your program. You could overhaul parts of your implementation without affecting other objects. It also lessened time for recompilation since you only needed to recompile the objects that you altered instead of everything.

OOP is basically functions calling functions calling functions, within and between objects.

EDIT: Also, with modular function design, you don't need to twist you brain debugging your program. You only need to find where it broke then confirm that the function calls involved are doing what they are supposed to do. It's easier to catch errors that way than putting all your code in only one long section.

Edited by omikron48
Posted (edited)

I used to be a disciple of GOTO. No more. GOTO is bad. Period. The problem with GOTO is it leads to what some call spaghetti code. It always ends up such a intertwined mess that if you look at it wrong, it breaks. Even when I have to write something in a language that supports GOTO, I will avoid using GOTO like the plague. When writing in AutoIt, use functions. What do you think most of the UDF commands in AutoIt are? They are simply functions. Notice the include files you have to use when you use many of the commands? Ever open of these files in SciTE to see what's in it? Functions and more functions.

Let GOTO die a peaceful death and join the world in what most coders now do. They don't use GOTO - for good reason.

Edited by Volly
Posted

GOTO (and GOSUB) should be carried away on the backs of Dinosuars. There are a few other ancient concepts that could be added to that list.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Posted (edited)

Ok! ok!...

First said, I obey the majority if my strayed ways disturb others. I won't post any further about praising Goto (if I'm not asked to).

I'll just live with it as it never existed.

@MHz:

Respect.

@Fulano:

All due respect, but the power of goto was never in question, it was the sanity of using it when other options were available. While it's true that every control structure could be recreated with only je and jne, why go through all the pain of reinventing the wheel?

- So, you admit Goto is powerful. So the misuse is the problem.

- There's a difference between recreating a whole control structure with je's and jne's on one hand, and using the je only on the other hand.

@Beege:

The Weak? :) I think thats a bit much. Were talking about extremely smart computer scientists that pushed the use of structured programming.

Just kidding about the "weak" :) more like an childish tease. That's why I put the ninja :D

@bo8ster:

from experience gotos lead to the dark side. They are powerful and great however their use always leads to always lead to maintenance issues.

I agree with you. Please, be honest: what image do you have in mind when pronouncing the word "POWER" loudly?

Give the MAN atomic power and he'll be more... destructive. So, I agree with you :(

Their use is a sign of poor programming, laziness or a lack of understanding of the language. If you know better there is no excuses for using them.

Poor programming? laziness?? lack of understanding of the language?!? Well... yes. Right again. I know people who, in MS Word, use 'enter' multiple times to custom-space the paragraphs instead of formatting them and lots of 'space' taps instead of aligning with tab's or ruler. So each tool has its own use.

I have seen first had ‘smart’ people use them instead if catch statements because they are ‘clean, simple and quicker’. This lead to a three fold blow out in development time because they were too stupid and lazy to do the right thing even after they were warned. I could go on.

I'm afraid I don't understand.

I believe they are like drugs, they ultimate lead to no good. Good to see they are removed from the language.

Any abuse is harmful (like my mood for talking to you, guys :)).

@omikron48:

You are right, too. Word by word. I know OOP and IMO it's comparable to stepping from the B/W to the color television. In C++ Goto would have been useless, indeed. But note there's a difference between a programming language and a scripting language. This is because in programming, you have many tracks that inter-communicate, many variables and the most important - variables altering other variables by the mean of yet other variables. Thus, you're totally limp without custom functions or classes. In simple scripting, say batching, you use like 10 vars, most of the time a couple of tracks by the mean of conditional controls (it's linear basically). Reusability of functions is not related to a specific automation script. What reusable custom functions do you use in automating an installation software? I myself, am using not only built-in functions but custom, too, to avoid re-writing code. It's about ergonomy, not necessity. In an automation script like the one I presented above you I could, as seen, use a single code block with Goto without using functions. Still, I consider functions a big step forward in batching.

You can't compare programming with scripting. Why not implement vectors, too in AutoIt? And as they're implemented, discontinue the arrays.

However, I know that AutoIt is not only a batching solution (and what a solution! B) ) but a programming one, too.

@Volly, GEOSoft:

I took a look in the 'include' folder. Lots of libs of functions. All reusable. Don't get me wrong: I like functions and use them in AutoIt. But I use them when I really need a them. Functions are not intended to be a replacement for loops. For example, I don't create and then recursively call a function after a nested 'if' condition, instead of using "do/until". I use mostly non-specific functions, as specific ones related to certain windows, vars, controls aren't too reusable.

There are a lot of functions in AutoIt, dealing with everything one could need and even more. Seeing all these, I didn't know whether 'goto' or similar command would exist but intuitively searched in AutoIt Help for 'goto' as I said: "sure it is there somewhere...". And it hit me :)

@<all>:

Really last words:

A good programming comparison is with building a house. Why use a wall when you need a brick? In assembler you build with bricks and it's a menace to raise a large building this way. It's easier to use already made walls when building it, I totally agree. But what about the times when you need just a quarter of an wall (unusual case)? That's why I said Goto was versatile and quick (in conjunction with do/until, functions etc.). To be honest, when I use nested functions where Goto was fit, I feel like mounting the pre-made wall and then demolishing it to remain the last brick I need.

If others use bricks to conceive wacko spaghetti buildings, it's because they had that in mind and they materialized that. This shows the freedom (sometimes the insanity) of using bricks instead of walls.

And bricks are useful more when building a small house with few or many small rooms, than when building skyscrapers.

All in all, I have to admit that I didn't really encounter a situation to desperately need Goto. As I saw above, I can use Switch with its surprisingly ingenious ContinueCase. The loss isn't critical after all.

Goto, may you frolic in the evergreen fields in heaven ;)

Edited by mireazma
Posted

I was somewhat resistant when the crusade to stamp out the GOTO first hit, arguing that their were rare instances where it was appropriate. I still believe that to be true, but I decided I'd rather have a job, so I adhered to the companies standards. After a while, using the command never even came to mind. I guess I'd become more "disciplined".

I was happy to see Volly use the term "spahgetti code", as that's always been my favorite term for the convoluted unmaintainable crap that was prevalent years ago.

Another favorite phrase of mine that applies to DP, um, make that IT, is: "There are a million ways to skin a cat"

So here's one take on the requested logic flow (if I'm understanding you correctly)...

#include <GUIConstants.au3>
#include <GuiButton.au3>

; INITIALIZATION----------------------------------------------------------------
Global $Num_Buttons = 7, $field
Global $Control_Button[$Num_Buttons]
Global $Control_Array[$Num_Buttons][2] = [["Date", "*"],["Serial","*"],["Number",""],["Reg No",""],["ID","*"],["Date In",""],["Date Out",""]]; title, priority
Global $Control_Data[$Num_Buttons]

; MAIN -------------------------------------------------------------------------
Display_GUI()
Process_Buttons()
Exit

;-------------------------------------------------------------------------------
Func Display_GUI()
    GUICreate("", 120, 240)
    For $x = 0 to $Num_Buttons - 1
        $Control_Button[$x] = GUICtrlCreateButton($Control_Array[$x][0] & $Control_Array[$x][1], 20, 20 + $x * 30, 80)
    Next
    GUISetState(@SW_SHOW)
EndFunc

;-------------------------------------------------------------------------------
Func Process_Buttons()
    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $Control_Button[0] to $Control_Button[$Num_Buttons - 1]
                $field = $msg - $Control_Button[0]
                Process_Input($field)
;               Process_Input[$field]($field) ; if you prefer separate process functions
                Reset_Focus($field)
            Case -3
                ExitLoop
        EndSwitch
    WEnd
EndFunc

;-------------------------------------------------------------------------------
Func Process_Input($x)
    MsgBox(1, "", "Processing field: " & $Control_Array[$field][0])
; do the voodoo that you do here
EndFunc

;-------------------------------------------------------------------------------
Func Reset_Focus($x)
    For $y = $field + 1 to $Num_Buttons - 1
        If $Control_Array[$y][1] Then
            GUICtrlSetState($Control_Button[$y], $GUI_FOCUS)
            ExitLoop
        EndIf
    Next
; add another loop if you want it to roll-over to the first field   
EndFunc

(Yes, I'm very fond of indexing/subscripting)

Posted (edited)

What reusable custom functions do you use in automating an installation software?

This is the base script I use as a template for the software installations script I make:

#include <Misc.au3>
_Singleton("AutoIt Automated Script")
Opt("MustDeclareVars", 1)
Opt("ExpandEnvStrings", 1)
HotKeySet("{PAUSE}", "_Close")
Func _Close()
    Exit
EndFunc
Func _ControlClick($title, $text, $controlID)
    WinWait($title, $text)
    BlockInput(1)
    WinActivate($title, $text)
    Sleep(200)
    ControlClick($title, $text, $controlID)
    BlockInput(0)
EndFunc
Func _Send($title, $text, $output)
    WinWait($title, $text)
    BlockInput(1)
    WinActivate($title, $text)
    Sleep(200)
    Send($output)
    BlockInput(0)
EndFunc

Global $scriptname = StringReplace(@ScriptName, ".exe", "")
Global $ininame = "_" & $scriptname & ".ini"
Global $section = "Options"
If Not FileExists($ininame) Then
    MsgBox(0x2030, "Error", "No """ & $ininame & """! Writing empty .ini file.")
    _CreateINI()
    Exit
EndIf

Global $exec = IniRead($ininame, $section, "Path", "DEFAULT")

Run($exec)
If Not @error Then
    WinWaitClose
EndIf

Func _CreateINI()
    Local $file = FileOpen($ininame, 2)
    FileWriteLine($file, ";INI file for " & $scriptname)
    FileWriteLine($file, ";")
    FileWriteLine($file, ";INI file format is:")
    FileWriteLine($file, ";[SECTION]")
    FileWriteLine($file, ";KEY = VALUE")
    FileWriteLine($file, ";")
    FileWriteLine($file, ";Sample:")
    FileWriteLine($file, ";")
    FileWriteLine($file, ";Start entries here:")
    FileClose($file)
    IniRead($ininame, $section, "Path", "DEFAULT")
EndFunc

An example of an actual installation script I use looks like this:

Global $exec = IniRead($ininame, $section, "Path", ".\Lotus Notes 8 client BASIC\setup.exe")
Global $Username = IniRead($ininame, $section, "username", "<prompt>")
If StringCompare($Username , "<prompt>") == 0 Then
    While 1
        $Username = StringStripWS(InputBox("Input Prompt", "Enter Username:", "", "", 200, 60), 3)
        If @error == 0 And StringLen($Username) > 0 Then
            ExitLoop
        EndIf
    WEnd
EndIf
Global $Organization = IniRead($ininame, $section, "organization", "My Organization")
Global $InstallDir = IniRead($ininame, $section, "installdir", "C:\Notes\")
Global $DataDir = IniRead($ininame, $section, "datadir", "C:\Notes\Data\")

Run($exec)
If Not @error Then
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "WARNING: This program is protected by copyright law and international treatie", "[TEXT:&Next >]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "I &do not accept the terms in the license agreement", "[TEXT:I &accept the terms in the license agreement]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "I &do not accept the terms in the license agreement", "[TEXT:&Next >]")
    _Send("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Organization:", $Username)
    _Send("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Organization:", "{TAB}")
    _Send("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Organization:", $Organization)
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Organization:", "[TEXT:Only for &me  (Single User Install)]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Organization:", "[TEXT:&Next >]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Change...", "[TEXT:&Change...]")
    _Send("", "Select a location for installation of program files.", $InstallDir)
    _Send("", "Select a location for installation of program files.", "{ENTER}")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Change...", "[TEXT:C&hange...]")
    _Send("Lotus Notes 8.0.1 (Basic) - Install Wizard", "Change Data Destination Folder", $DataDir)
    _Send("Lotus Notes 8.0.1 (Basic) - Install Wizard", "Change Data Destination Folder", "{ENTER}")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "&Change...", "[TEXT:&Next >]")
    _ControlClick("", "This feature requires", "[TEXT:&Next >]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "Make Notes my default email program.", "[TEXT:&Install]")
    _ControlClick("Lotus Notes 8.0.1 (Basic) - Install Wizard", "The Install Wizard has successfully installed Lotus Notes 8.0.1 (Basic).", "[TEXT:&Finish]")
    WinWaitClose("Lotus Notes 8.0.1 (Basic) - Install Wizard", "The Install Wizard has successfully installed Lotus Notes 8.0.1 (Basic).")
EndIf

The neat thing about it is that the automated clicking and sending part of my installation script uses input that is roughly the same as the output I get from the logging script I use when I do a sample manual installation. I just copy/paste the text labels of the clicked elements and type up the input keys that need to be sent.

Edited by omikron48
Posted

@Spiff59:

Wow. Professional approach. It will take me some while to process that, as I never used Gui's but in a simple tutorial. it looks like it's Gui time.

@omikron48:

It's nice to automate an installation based on a previous one.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...