Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Go to?

by Ronnie (Scribe)
on Apr 05, 2006 at 09:39 UTC ( [id://541316]=perlquestion: print w/replies, xml ) Need Help??

Ronnie has asked for the wisdom of the Perl Monks concerning the following question:

Good morning cellmates, I've been tasked with converting an old UNIX scripted system into Perl. This in itself is not a great - though long and tedious - task, however it occurs to me that this system could be much improved upon espescially when jobs failed! I won't tell you what has to be done when a job fails as well......the shame the shame! Anyway I was going to implement a method that I used in the old mainframe - memories! - days but there doesn't appear to be a "go to" facility in Perl can this be true? If so is there any other method available that will allow me to jump code given certain conditions?
Example :- A script has 50 programs to run and fails at step 35. At the moment the programmer has to make a copy of the original script, removes the first 34 steps and then runs this "new" script once before scrapping it. I want to automate failures using the original script. To this end each program within this script becomes a step - prog 10 is step 10. After completeing a step the step number is written to a file (if the run finishes completely the step file is deleted!) On running this script the first thing done - after standard parameter validation - is to see if the stepfile exists. If it does this is a re-run and whatever step number this file contains is where the script re-starts. This is the reason for a goto. I don't think that my program logic is flawed here as the goto is only to be used as part of this automatic re-start code and as such will only be used once.

Sorry but some of the reponses are idealogical clap trap! "I've never used a goto" indicates a lack of experience not knowledge. Unlike some people I know why using goto is frowned upon - and not just in Perl Cobol SCL etc - but that doesn't alter the fact that there are times and places where it's use is required! This is one such case! I want to AUTOMATE job failures - this means that the code doesn't get changed after a failure,it's simply well written enough to be re-run once the problem has been circumvented! Now maybe some people like to tinker with the same code everytime a job failure occurs but I prefer to get on with new work and if the inclusion of a (shock horror ) goto is going to allow that progress then that's what should be done. So please whether you've been programming for a couple of years or like some of us 20 odd years please respond to the question not demonstrate petty prejudice! One last thought for the prejudiced amongst us.... if it turns out that the only way to do something - and don't tell me this will NEVER happen because every single platform that I've programmed for has had such an occasion - is to use a goto what will you do? Say to the boss it can't be done because it offends me? I don't think so!

Replies are listed 'Best First'.
Re: Go to?
by McDarren (Abbot) on Apr 06, 2006 at 02:43 UTC
    Another member of Perlmonks, for whom I have a great deal of respect, has the following quote in his signature line:
    Examine what is said, not who speaks -- Silence betokens consent
    So with that in mind....
    "I've never used a goto" indicates a lack of experience not knowledge.

    Yes, perhaps it does. However, I think you misunderstand me. I actually said "in that time I've never used a goto" - referrring to the length of time I've been using Perl for.

    Sure I've used goto's in the past. In fact, the BASIC programs I was writing in 1978 would have been littered with them. But this is 2006, and this is Perl. And thankfully, Perl provides us with a rich set of loop control and program flow features which help us to write more structured programs, and hence avoid bouncing all over the place with goto's.

    Unlike some people I know why using goto is frowned upon

    Good for you!
    And which people would that be, btw?

    doesn't alter the fact that there are times and places where it's use is required! This is one such case!

    With respect, I disagree. I've already given you a working example of how you can make do without one. And monarch, cdarke and Roy Johnson have also given you pointers to methods that can avoid it.

    please respond to the question not demonstrate petty prejudice!

    Your original question asked if there was a "go to" in Perl. I told you that there was, and I gave you links to the appropriate documentation.
    How is this not responding to your question?

    is to use a goto what will you do? Say to the boss it can't be done because it offends me?

    In such a situation, I would use a goto. I'm not quite sure where you got the idea that the use of goto offends me. All I said was "looking to use a goto is generally a sign that your program logic is flawed". And, it generally is. As I've been learning to use Perl, there have been several occassions where I have found myself thinking "mmm, I need to use a goto here". And without exception - after doing some reading or seeking advice from others - I have found that it wasn't necessary at all.

    Cheers,
    Darren :)

      And thankfully, Perl provides us with a rich set of loop control and program flow features which help us to write more structured programs, and hence avoid bouncing all over the place with goto's.

      What is a next/last but a goto? In fact, next LABEL; or last LABEL; are both gotos without much of a disguise. The only constraint upon them is that the label must be on a loop enclosing the next/last statement. next/last will even work within a subroutine.

      use strict; use warnings; sub foo { next LOOP; } LOOP: for ( 1 .. 10 ) { if ( $_ < 5 ) { foo(); } print "$_\n"; } ---- Exiting subroutine via next at ./test.pl line 7. Exiting subroutine via next at ./test.pl line 7. Exiting subroutine via next at ./test.pl line 7. Exiting subroutine via next at ./test.pl line 7. 5 6 7 8 9 10
      Yes, a warning is thrown, but the code still works as expected.

      As for a goto being an indication of flawed program logic, that's completely and utterly not true. Why do you use next/last? Here's an example:

      while ( <FH> ) { next unless length; # Skip blank lines next if /^#/; # Skip comments next if /\bSKIP\b/; # Skip lines that want to be skipped # Do something useful here }
      Pretty easy to understand, right? Let's see what happens if next/last are disallowed because they're goto in disguise . . .
      while ( <FH> ) { if ( length ) { if ( !/^#/ ) { if ( !/\bSKIP\b/ ) { # Do something useful here } } } }
      I hope the point is made.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
        I hope the point is made.
        Yes, the point is most definitely made, and taken :)

        And I'll be the first to admit that I use next and last quite liberally.

        And I'll also admit that I was quite surprised to find that goto hardly rates a mention in PBP - I suppose that can be taken to indicate that the author also condones its use.

        However, I still think that I'll continue to avoid goto as much as possible in the future ;)

        Cheers, and thanks..
        Darren :)

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Go to?
by McDarren (Abbot) on Apr 05, 2006 at 09:55 UTC
    Perl does indeed have a goto function, but the last person that used it had his compter invade Poland whist his back was turned ;)

    But seriously, looking to use a goto is generally a sign that your program logic is flawed, and perhaps some re-thinking is in order.

    Update: I didn't realise (until I saw the response from monarch) that you had updated your original question with the example - obviously meant as a reply to this node. However, I still stand by what I said above. I've only been using Perl for a couple of years, but in that time I've never used a goto. I've no doubt that there may be the very odd situation where it's use is warranted, but I've yet to encounter one.

    Cheers,
    Darren :)

      Making blanket statements that goto is evil suffers from the dangers of Cargo Cultism.

      This is not to say that there isn't wisdom encapsulated there, but if it's learned behavior by ROTE rather than comprehension then the inherent wisdom is lost.

      goto, like a gun - isn't evil. It's what you do with it that counts.

      I'll not belabor the point already stated clearly by others.

      That being said - I haven't had a reason to use goto in perl personally. I'm intrigued by the prospect and I want to know more.

      That being said - I don't know if the OP has clearly stated what that reason is in his case. Rather they've been focusing on fending off the initial kneejerk reaction. That reaction however should have been expected.

      I don't see that it's necessarily wrong to question the motivation behind the choice however, since it's something that cuts against the grain of the party line concerning 'structured programming'. What I mean by that is simply that for those of us who started programming with a flavor of BASIC and then moved on to other languages, or who took an academic journey to become programmers - we have been taught that using goto is usually a sign that you're doing something 'wrong'. If nothing else it's a sign that you should be thinking about what you're doing very carefully - and the OP is clearly doing that.

      Ronnie can you please elaborate on the subject?



      Wait! This isn't a Parachute, this is a Backpack!
        Making blanket statements that goto is evil suffers from the dangers of Cargo Cultism.

        I couldn't agree more!
        By the way, who was it that said that goto is evil? (certainly not me)

        but if it's learned behavior by ROTE rather than comprehension then the inherent wisdom is lost.

        My sentiments exactly.

        I might also add that making assumptions (and drawing conclusions) about one's level of knowledge and experience based on minimal evidence often does the recepient no justice at all, and in some cases can cause hurt and resentment - which does nobody any good.

        But it's okay, because I'm not the type of person to take any of this personally :)

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Go to?
by monarch (Priest) on Apr 05, 2006 at 11:50 UTC
    I'm sad to see that the author of this thread has been downvoted.. I'm speculating that the reason for this is the opinion by many that goto is just plain wrong.

    The truth is that goto is a tool in the perl arsenal that can be used for good and evil. If anyone here is writing code that isn't indented properly, or relies on side effects from operations, or indeed doesn't parenthesise their arithmetic and logical instructions to prevent unexpected order of evaluation then they, too, should be viewed with disdain from the goto purists.

    At least the thread author made a good attempt to justify the reason for needing goto; indeed the author needn't have justified anything. Perl has a goto statement and thus that's reason enough to be allowed to use it.

    As a final note, I don't remember the last time I used goto in Perl or C programming (thought I've used it liberally in assembler).

    instructional comment: one way of avoiding goto is to create a while loop and, should you want to skip something, use the next statement within the loop.

Re: Go to?
by TrekNoid (Pilgrim) on Apr 06, 2006 at 20:36 UTC
    So please whether you've been programming for a couple of years or like some of us 20 odd years please respond to the question not demonstrate petty prejudice!

    The problem is, they *have* been responding to your question... You've just forgotten what you originally asked:

    but there doesn't appear to be a "go to" facility in Perl can this be true? If so is there any other method available that will allow me to jump code given certain conditions?

    You *did* ask if there were any other methods available to jump code, and Perl has a multitude of ways to do that without resorting to the infamous 'goto'.

    And I, too, am a reformed mainframer with over 20 years in the business, and I wrote of my share of GOTO and PERFORM-THRU in my day... but in the last seven years (since I've been writing Perl) I haven't *needed* one.

    That doesn't mean there's not occasions where it's appropriate, I just haven't had any reason to do it.

    You asked for other methods... you shouldn't be surprised that you got 'em...

Re: Go to?
by jdporter (Paladin) on Apr 06, 2006 at 15:32 UTC

    In believing that you need to use goto to get your job done, you probably have an XY problem.

    We're building the house of the future together.
Re: Go to?
by Roy Johnson (Monsignor) on Apr 05, 2006 at 15:56 UTC
    Have an array of steps, and have your script take an optional start-at parameter.
    my @steps = (sub {...}, ...); my $start_at = shift || 0; for my $this_step ($start_at .. $#steps) { $steps[$this_step]() or die "Oops! at step $this_step\n"; }

    Caution: Contents may have been coded under pressure.
Re: Go to?
by eric256 (Parson) on Apr 05, 2006 at 17:04 UTC

    "Sorry but some of the reponses are idealogical clap trap! "I've never used a goto" indicates a lack of experience not knowledge"

    Err..Isn't that just as much a crap response as you claim they are? I have used goto, back in the good old days of basic and by god i was glad to get rid of it as soon as i learned about functions ;) There are many ways to solve your problem, goto is 1 of them sure, but it is one that many of use prefer to avoid. That doesn't signifiy a lack of experience or knowledge, its just a preference. Your desire to use goto even when there are alternatives is fine, but realy, don't bash the people who just tried to help you. If you are too high and mighty for this crowd then don't ask for help, if you arn't then be gratefull for the help you get.

    For my two cents i would probably do something like make each job a job.x.pl file where x is a number, then do some magic to start at whatever number you want and system those files....or maybe not. It realy depends on what your programs do.

    BTW a very quick google on "perl go to" results in "are you sure you don't want perl goto" so you might just be getting -- for not searching first ;)


    ___________
    Eric Hodges
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Go to?
by roboticus (Chancellor) on Apr 06, 2006 at 03:05 UTC
    Ideological Clap Trap--
    #!/usr/bin/perl -w use strict; use warnings; sub step_1 { print "Programming step 1\n"; # do junk } sub step_2 { print "Programming step 2\n"; # more junk } sub step_3 { print "Programming step 3\n"; # lots more junk } my @STEPS = (\&step_1, \&step_2, \&step_3); my $SKIP=shift || 0; for my $ST (0 .. $#STEPS) { if ($ST < $SKIP) { print "Skipping step $ST\n"; } else { &{$STEPS[$ST]}; } }
    --roboticus
Re: Go to?
by cdarke (Prior) on Apr 05, 2006 at 13:49 UTC
    Hope I understood your problem correctly.
    You could store your program calls in an array. Not sure how you are calling the programs, but let's say you are using system in a simplistic world:
    for my $prog (@programs) { system($prog) }
    To disable one of the programs, just delete the element from the array. The 'step number' is the index to the array. If the code is more complex then put each step in a subroutine and have an array of subroutine references. The steps to run (or omit) could be passed on the command line.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Go to?
by jhourcle (Prior) on Apr 06, 2006 at 16:36 UTC

    From what I understood of the original problem -- Ronnie has to port some code over to Perl, from some shell scripts.

    It makes perfect sense to me to try to keep the logic flow the same between programs for the first iteration. If the program's logic was working, it makes no sense to try to refactor it at the same time ... we have no idea what the deadlines are, or any other constraints on this project, and I don't personally see the point in spouting ideology on this particular point, as goto has its uses.

    I've used goto in Perl quite a few times in the past year. Most frequently, it's inside functions like AUTOLOAD that generate closures, and then goto the new function ... or any other time I insert logging functions in a child that I don't want to show up if the parent looks at caller:

Re: Go to?
by SamCG (Hermit) on Apr 11, 2006 at 00:23 UTC
    Ronnie,

    I'd suggest you mark updates as such. Coming to this post the first time I was quite surprised by your apparent vehemence for an initial post. It turned me off (though I saw later that it was a response).

    I sort of agree with you -- if a go to function exists and there's a reason to use it, ignore ideology. That said, I've never really had a desire to use a goto statement. Maybe that is inexperience. Though I am quite confused about your rationale; I believe I've written plenty of code that handles job failures just fine without modification and doesn't use goto statements. Your situation could be different, though, and personally I don't care (and won't even think badly of you)if you litter your code with goto's.

    I don't think those who've responded with you have been quite as harsh or dogmatic as you seem to think. Maybe you should come back to this thread after a week or so. Forgive me for suggesting how you should respond, but instead of a long diatribe you could have simply said something like "A goto is appropriate for my situation".

    And now I've spent enough time looking at this.



    -----------------
    s''limp';@p=split '!','n!h!p!';s,m,s,;$s=y;$c=slice @p1;so brutally;d;$n=reverse;$c=$s**$#p;print(''.$c^chop($n))while($c/=$#p)>=1;
Re: Go to?
by jplindstrom (Monsignor) on Apr 11, 2006 at 14:53 UTC
    There is a framework for doing exactly what you ask for (skip previously finished steps): Commands::Guarded.

    It may not be suitable for your first version of the converted script, but maybe for further development.

    /J

Re: Go to?
by derby (Abbot) on Apr 11, 2006 at 16:44 UTC

    On running this script the first thing done - after standard parameter validation - is to see if the stepfile exists. If it does this is a re-run and whatever step number this file contains is where the script re-starts. This is the reason for a goto. I don't think that my program logic is flawed here as the goto is only to be used as part of this automatic re-start code and as such will only be used once.

    Hmm ... how about something like a dispatch table keyed by order:

    my %cmd_steps = ( 1 => "/bin/ls", 5 => "/bin/uname", 10 => "/bin/dmesg", 15 => "/bin/date", 20 => "/bin/hostname", 25 => "/bin/mount", 30 => "/usr/bin/dir", 35 => "/usr/bin/lpq", 40 => "/bin/ps", ); my $next_step = 15; foreach my $step ( sort { $a <=> $b } keys %cmd_steps ) { next unless $step >= $next_step; print "Step: $step - Cmd: $cmd_steps{ $step }\n"; my $out = `$cmd_steps{$step}`; print $out; print "="x80, "\n"; }

    Sure if you have a huge number of steps you'll gain a few cycles using goto vice spinning over unused steps but hey ... tradeoffs.

    -derby

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://541316]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-26 00:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found