Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Number of times I've used goto in Perl

by vroom (His Eminence)
on Apr 18, 2000 at 22:40 UTC ( [id://7947]=poll: print w/replies, xml ) Need Help??

Vote on this poll

Never
[bar] 60/64%
Once
[bar] 7/7%
Twice
[bar] 6/6%
3-5 times
[bar] 6/6%
5-10 times
[bar] 3/3%
More than 10 times
[bar] 10/11%
Everyday
[bar] 2/2%
94 total votes
Replies are listed 'Best First'.
goto hell
by bazman (Initiate) on Apr 20, 2000 at 13:52 UTC
    I read something recently that said you could tell if someone was a programmer if you told them to go to hell and they considered the 'go to' more harmful than the 'hell'. Baz
      print "that was stupid but slightly entertaining" print "hahaha, i will now trap you in an infinite loop" hell goto hell
        Ctrl+C
Re: Number of times I've used goto in Perl
by Casteele (Novice) on Jun 04, 2016 at 00:52 UTC

    There needs to be an answer for "As often/little as needed (but not more or less...)." IMO, "goto" is just another tool in a Perl programmers toolbox. It should be used when/where it's appropriate, and not when it's not.

    Having been writing programs since the early 80's, i remember when the whole concept of "goto is evil" arose, not because of goto itself, but because of how many times code would become hard to follow and read (referred to as "spaghetti code"). These days, I do not see that kind of code much, but I do see code which some programmers do all kinds of hard to read/follow "tricks", *just* to avoid the use of goto. This makes no sense to me given the whole concept of "avoid goto" arose from the idea that such code was hard to read/follow. Why does making the code hard to read/follow at the *other* extreme make such code "better?" It doesn't.

    When you develop in assembly language, for example, it's nearly impossible to avoid the use of jump/branch statements (upon which goto is based/modeled) in non-trivial code, and still write code which is fast and small--and yes, easy to follow. To do the same thing without any form of branch/jump/"goto", would require a lot of extra confusing code, or the use of many more subroutines ..and the extra overhead of calling them! It's faster and less code to simply change the current execution address than it is to.. save the registers/flags/call data/other state data, allocated stack space, transfer to a new routine, load the data back, process it, save it all back again, return from the routine, restore everything again, and resume execution. Sounds like a complicated mess like that? It is!

    This whole issue, to me, is similar to the issue of code comments/documentation. I've seen far more people who do not comment/document--or just as bad, people who add comments when they're not necessary because the code is already self-evident.

    IMO, we need less people preaching "Never use 'goto'!" and more people preaching "Program intelligently; Use what you need and keep it clean, simple, and understandable."

      Program intelligently;

      I wholeheartedly agree.

      Unfortunately there is a large and apparently growing section of the (IT) community that seem to want be able to program by rote; to mechanically follow a recipe, a set of rules followed verbatim: stand up and say "Yay!" for 5 minutes; sit down and write 10 minutes of non-production code; swap seats and write 5 minutes of production code; 20 minutes of watching "XYZ passed" scroll up the screen. Rinse and repeat until the end of the day.

      New day, 5 minutes standing. "What did you do yesterday?". "I wrote 13 new tests". {collective} "Yay!".


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
      In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
RE: Number of times I've used goto in Perl
by chromatic (Archbishop) on Apr 19, 2000 at 00:21 UTC
    Does a named loop count? Something like:
    TOP_OF_LOOP: while (1) { # do this for (1 .. $some_big_number) { $foo = do_some_function($_); if ($foo % $_ = $some_smaller_number) { next TOP_OF_LOOP; } # do something else } } }
    In both cases, your program flow probably needs help. :) (Okay, I'm really bad with configuration files.)

    (And, yes, okay, it's an implicit goto. I'm guilty of it once in an AUTOLOAD, though.)

      Where is the goto in your example?
      IMHO, breaking flow using 'next' counts.

      That's almost as bad as an infinite 'while(true)' construct! :)
        What's so bad about while (1) { something; next if somethingmore; last if somethingelse; } ?

        I use it all the time.

         -Kaatunut

RE: Number of times I've used goto in Perl
by dlc (Acolyte) on Apr 19, 2000 at 21:02 UTC

    Goto is almost required when you use the AUTOLOADer, as such:

    sub AUTOLOAD {
        no strict 'refs';
        $AUTOLOAD =~ s/.*:://;

        *{ $AUTOLOAD } = sub { return ${ $AUTOLOAD }; };

        goto &{ $AUTOLOAD };
    }
RE: Number of times I've used goto in Perl
by Vane (Novice) on Apr 18, 2000 at 23:44 UTC
    warn "you can do better" if goto;

      I tend to use goto quite liberally. For example, below, I want to exit the sub if the $project does not have the IconView initialized yet. Also, if no items were selected, I want to return. In both cases I want to give the same warning and return.

        It is possible to avoid using goto here:
      1. eval the get_selected_items and check for error
      2. do a return instead of goto
      3. ...

      But, to me, this seems like it is much easier (and clearer) to use goto instead of coming up with all possible structures and so on just to avoid using goto.

      goto NO_EXIF unless (defined($project->{LG}->{IMG_ICONVIEW})); my @img_selected = $project->{LG}->{IMG_ICONVIEW}->get_selected_it +ems(); my @dock_selected = $project->{LG}->{DOCK_ICONVIEW}->get_selected_ +items(); ## check that any images are selected if (scalar(@img_selected) + scalar(@dock_selected) < 1) { NO_EXIF: GUIFunctions->warn("Some message"); return; }
RE: Number of times I've used goto in Perl
by Simplicus (Monk) on Apr 19, 2000 at 18:51 UTC
    I only used goto once in my life (explicitly)(I'm not counting uses of goto made by others in packages or modules I have included. I'm not a snob, I've just never found it useful. A language construct should clarify, not obfuscate, and goto almost always "spaghettifies" the code.
    If someone can come up with an example of an instance where goto is necessary for the purpose of clarification in code, I'd love to see it.

    Simplicus
      I have never used GOTO in Perl, but in Visual Basic, which I learned in school. There
      it's used for error handling where you would say:
      On Error Goto ErrHandler
      and then construct an appropriate subroutine underneath the ErrHandler tag to handle the error.
      I believe the reason that VB uses GOTO in that situation is because an error can
      conceivably occur at anypoint, and you want to be able to catch it immediately, instead
      of wrapping things in a TRY..EXCEPT model. But that type of unexpected error seems to me
      more of a problem in an 'event driven' piece of code, and not so much the style with which
      Perl is used. Plus I think that it is more difficult to use than other methods I have seen.
      So I personally cannot see the value of GOTO in Perl, though I do not deny it's validity, or the
      skills of anyone who uses it.
      just my $0.02..
      If someone can come up with an example of an instance where goto is necessary for the purpose of clarification in code, I'd love to see it.
      necessary? I doubt many examples exists. However, I doubt there are many examples showing OO to be necessary for the purpose of clarification (or any other purpose). Necessary implies there not being an alternative. In Perl, there's almost always an alternative. Whether it's for goto, or OO.
RE: Number of times I've used goto in Perl
by Jonathan (Curate) on Apr 19, 2000 at 14:50 UTC
    Surely Loop naming doesn't count. I've never used goto in any language. But, they sound fun, think I'll start ;-)
Re: Number of times I've used goto in Perl
by ikegami (Patriarch) on May 06, 2018 at 08:13 UTC

    I found goto useful in C.

    char *p1 = alloc(); if (p1 == NULL) goto ERROR; char *p2 = alloc(); if (p2 == NULL) goto ERROR2; char *p3 = alloc(); if (p3 == NULL) goto ERROR3; ... return 1; ERROR3: free(p2); ERROR2: free(p1); ERROR: return 0

    But with Perl's reference counting and destructors, this model isn't necessary.

      In C, any time you use the switch statement, you're really using (forward) goto in disguise.

        for, while, if, and more can also be implemented using a jump. That doesn't matter. The problem with goto isn't that it's a jump instruction; the problem is the resulting lack of code structure. For code to readable, it you should composed of "blocks". Prematures exits (next, last, return, die, and goto as used in my C example) are an exception as they can actually improve readability. This is why they don't necessarily have the same problem as goto.

GOTO? No, but...
by The Alien (Sexton) on Apr 20, 2000 at 23:04 UTC
    I have never used goto in perl. I almost never used it in BASIC. But I did use GOSUB a lot. Naturally, I have used last and even next (and once, redo) in Perl. I do not see this as any kind of sin, because it can clarify things nicely. I do not see that a hideously complex loop condition is better than some internal flow control in all cases.
    Of course, because of the nature of my work, others being able to grok my code easily is important. So I tend to write production code in a very 'natural languge' sort of format.
Re: Number of times I've used goto in Perl
by shmem (Chancellor) on Mar 26, 2015 at 07:45 UTC

    Three times. here, here and here.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Number of times I've used goto in Perl
by LanX (Saint) on May 06, 2018 at 21:57 UTC
    Many times!

    Most languages are full of "gotos", they are just hidden behind other expressions like break or throw (yes exceptions are gotos, think about it)

    The fact that most useful cases of flow control can be solved without goto doesn't mean all useful cases are covered.

    It's like not giving heroine to a terminal cancer patient, because he could get addicted.

    Don't let religion rule over logic.

    Even if prophets like Wirth and Dijkstra preached against it.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Wikisyntax for the Monastery

      yes exceptions are gotos, think about it
      Some people even used to criticise exceptions by stating that they are like INTERCAL's COMEFROM.
RE: Number of times I've used goto in Perl
by IndyZ (Friar) on Apr 19, 2000 at 00:43 UTC
    I think this a a test by vroom to see who deserves their monk status. Anybody who says that they've uses a goto loses 75% of their XP.
      Actually, if you've ever done much module/OO programming, you've probably used goto quite a lot, particularly if you write AUTOLOAD functions. From perltoot:
      When Perl tries to call an undefined function in a particular package and that function is not defined, it looks for a function in that same package called AUTOLOAD. If one exists, it's called with the same arguments as the original function would have had. The fully-qualified name of the function is stored in that package's global variable $AUTOLOAD. Once called, the function can do anything it would like, including defining a new function by the right name, and then doing a really fancy kind of goto right to it, erasing itself from the call stack.
      As such goto is used in quite a few modules, core or otherwise. CGI.pm, for example.
        Ok, perhaps the question should read: "How many times have you inserted the 'goto' keyword into one of your scripts?" CGI.pm and most others simply use the goto as part of the AUTOLOAD feature, so I let them slide....but, glancing through the standard modules, there are some exceptions: sigtrap.pm, autouse.pm, and (oh no!) even good old Carp.pm use 'goto' as a way of reaching another part of their script. Bleh! I'm still at 'never.'

        goto &sub is not a goto; it's a frame-removing version of return &sub;.

RE: Number of times I've used goto in Perl
by mcwee (Pilgrim) on Apr 20, 2000 at 23:07 UTC
    I'm one of the two monks who said that used GOTO once.

    I don't remember what I used it for, but I do remember feeling deep shame.

    PLease forgive my weakness-- I fall to me knees before my brethren and sistren and beg for mercy, understanding and absolution. I was a weak man then.

    The Autonomic Pilot

      Bless me father for I am about to sin.... I may have found a use for the goto but I thought I'd would consult with the elders prior to taking the plunge! I have one large perl script that drives a large data loading process every night. The script has a "main" subroutine that has roughly 30-40 steps - here's a snippet:

      sub main

      { ##>> 01001000:set output

      &set_output;

      ##>> 03001000:database up

      &database_up;

      ##>> 04001000:prior status

      &prior_status;

      ##>> 06001000:delete log records

      &delete_log_records; .........

      the "&" labels in "main" naturally call subroutines down in the body of the script. If our load process fails I want a way to "goto" the failure point in the script and continue processing by passing in a parameter that represents the step from which I'd like to continue. I can't think of another way of doing this with out rewriting the whole blessed script.

      Help O great ones!!

      Grasshopper

        Why not in main wrap blocks of calls in eval blocks and die when you hit errors?
Re: Number of times I've used goto in Perl
by tlhf (Scribe) on Mar 12, 2002 at 23:29 UTC
    I know this topic is all kinds of old, but, I have a very short script which checks if multiple servers are online. I also wanted it so that via optional command line options $loop (boolean) and $time (integer) it would loop until all the servers are online. At this point it would beep a lot.

    Yet rather than putting all the code in a big evil while() loop, or in a big evil sub, I thought sticking this at the bottom seemed to make a lot more sense, both code shortness and clarity-wise.

    goto START if ($loop && sleep($time||300));

    tlhf
    xxx
    I had always knew gotos were bad. Now I know that you can never know anything ;)

      In the case of long running daemons, I prefer to write that as:
      exec $0, @ARGV if $loop && sleep ($time || 300);
      Of course, that assumes you aren't collecting stats over multiple loops.

      The advantage of using exec instead of a goto (or loop), is that if there's a memory leak somewhere (be it in your script, a module or library you use, or a in perl itself), it will accumulate with a loop, but not with an exec.

Re: Number of times I've used goto in Perl
by Anonymous Monk on Apr 13, 2002 at 05:08 UTC
    Most people don't use goto because they don't know how. As a Cobol programmer, I use it all the time. I will use it in perl if I feel they need. Sometimes, it's better than having long loops where you can easily get confused. A nice goto can simplify things, but you have to know how to use it properly so you don't get in to endless loops. If you use a goto, you just have to make sure that you never return to that code and if you do that you get out properly. To those that say goto is poor programming, I say BS.
      I quite agree. The first language I ever learned was a rather primitive dialect of BASIC. There were no block IF statements, no NEXT, LAST, CONTINUE etc for while loops. The only branch commands were GOTO and GOSUB. One can write very clear, very well-structured code with GOTOs. However, the structure must be self-imposed since the language will not force you to write in a well-structured fashion. Saying that GOTO causes messy code is like saying that hammers cause squashed thumbs.

      The best description I have heard is that GOTO is like a stick of dynamite. Occasionally, when programming, you come across a large boulder in the middle of your path. While you *can* build an elaborate structure to go around it, it is often faster and more efficient to just blow it up. Just be careful not to bury yourself under tons of rubble when doing so.

      The other place to use a goto is anyplace you find yourself intentionally building an infinite loop. If you use a while(1) kind of construct, you are necessarily wasting CPU cycles evaluating a conditional which is always true. Building such a loop with GOTOs is just as easily readable, and more efficient.
Re: Number of times I've used goto in Perl
by HugoNo1 (Novice) on Sep 26, 2018 at 11:07 UTC

    Surprisingly nobody has commented on this nice use of the goto Function
    which exists only in Perl:

    sub newFuctionName { #Doing the same stuff as always ... } sub oldFunctionName { goto &newFuctionName; }

    Which has the nice effect:
    http://perldoc.perl.org/functions/goto.html

    it exits the current subroutine (losing any changes set by local) and immediately calls in its place the named subroutine using the current value of @_ .

    That way the Parameters won't be copied again when you go from oldFunctionName() to newFunctionName()
    which is very useful when you use a Library in many Projects and by the time find that you should rename this Feature.

    I also found this often in Modules as:

    sub _internalImplementation { #Doing the job ... } sub exportFunctionName { goto &_internalImplementation; }

      Well the people mentioning AUTOLOAD are actually talking about this version of goto. For example this post explicitly mentions goto &{ $AUTOLOAD };.

      The interest of goto isn't only about the fact that it transmits the current value of @_ to the called sub. Actually this is already the case when you do this:

      sub exportFunctionName { &_internalImplementation; }
      this is documented in perlsub
      If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.
      Actually I'm pretty sure there was a post about goto being slower than a simple function call (because it has to exit the the local changes) but I couldn't find it.

      So the main interest of goto lies in the fact that it doesn't add a function to the calling stack but instead replaces the current one. This means that with this code:

      sub A { goto &_A; } sub _A { B(); }
      The B function will never see &A in the calling stack, but only &_A. This can be used for debbuging, when you want to call a wrapper function (to print "About to enter &function", or check the input). I remember this question where this was precisely what the OP asked for.

        According to the official Documentation on

        https://perldoc.perl.org/perlperf.html#Assigning-and-Dereferencing-Variables.
        > The difference is clear to see and the dereferencing approach is slower.

        Dereferencing Variables is slower than Passing the References through.

        Therefore a Code like:

        package MyClass1; sub newFunctionName { #Doing my stuff } sub oldFunctionName { my $self = shift; $self->newFunctionName(@_); }

        As you would do it in other Programming Languages. Will be slower than the goto Implementation:

        package MyClass2; sub newFunctionName { #Doing the stuff } sub oldFunctionName { goto &newFunctionName; }

        That is what I exactly was looking for but couldn't find any concrete Example for it.

        This makes Sense because in the MyClass1::oldFunctionName() implemention the $self variable must be created in memory first which consumes CPU Processing Time.
        Which is confirmed by the official Documentation.

      Compare and contrast:

      #!/usr/bin/env perl use strict; use warnings FATAL => 'recursion'; my $i = 0; one(); sub one { print "$i\n" unless ++$i % 10; push @_, 'foo'; &one; }
      #!/usr/bin/env perl use strict; use warnings FATAL => 'recursion'; my $i = 0; one(); sub one { print "$i\n" unless ++$i % 10; push @_, 'foo'; goto &one; }

      Like much in the way of the Swiss Army Chainsaw you need to know precisely what you're doing if you run it with the guards off. Limbs can be easily lost.

        Hm ...

        ... is the goto version faster? Is this a way to have tail-recursion in Perl?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      > Surprisingly nobody has commented on this nice use of the goto Function

      Because nobody wanted to miss the point?

      That's a very different kind of semantics which could easily be bound to another keyword like "call".

      Perl has many examples of multiple semantics, e.g. eval

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        I got a syntax error because of detail that I might have missed out.
        And I searched on Google about it, but I could not find anything suitable Example about the correct usage.

        Actually I'm doing you a favor to the PerlMonks and to Perl with documenting this usage with useful examples.

        > > Surprisingly nobody has commented on this nice use of the goto Function
        > Because nobody wanted to miss the point?

        https://www.perlmonks.org/?node_id=1208600
        So, I notice more and more why this statement

        • is true
        • was commented anonymously

Re: Number of times I've used goto in Perl
by anonymized user 468275 (Curate) on Mar 25, 2015 at 17:55 UTC
    The problem one often faces is where at first sight standards and/or best practices conflict. In this case, there are at least three potentially conflicting factors that may need to be considered: 1) avoiding excessive nested blocks in terms of length and depth, 2) having a single point of return or exit from a routine or subroutine and 3) avoiding goto. Example:
    sub fred { # meeting all three requirements:- my ($t, $u, $v, $w, $x, $y) = @_; somelogger( 5, "fred", "start of fred"); my $ok = method1($t); $ok &&= method2($u); my $pid = open my $ph, "/somewhere/program $v |"; my $output = ''; $ok &&= method3( <$ph>, \$output ); close $ph; waitpid $ph,0; # and so on for functionality using $w, $x and $y (in worst case s +cenario) # if goto were used to jump to the exit point the # label would have been here. if ($ok) { somelogger( 5, "fred", "fred completed successfully"); } else { somelogger( 5, "fred", "error during fred"); } return $ok; }
    The point is that if goto were avoided using ifs, there would be one nesting level per error condition. Using &&= enables the code to cascade (without extra nested blocks) to the end whenever an error occurs. But many might consider the &&= too techy for the average programmer. Any thoughts, alternatives?

    One world, one people

      3) avoiding goto

      Avoiding goto is not an end in itself (unless one is religious about it, taking "avoid goto" as a tenet of the faith); it is only, at best, a means to some other end.

      Seems like you are doing two tasks in here, which is why you're even thinking of goto.

      ... &&= too techy ...

      A bit too techy and, for these old eyes, just plain difficult to see! I think I'd incline toward something like (all untested)

      sub fred { my ($t, $u, $v, $w, $x, $y) = @_; somelogger(5, "fred", "start of fred"); my $ok = 1; $ok = method1($t) if $ok; $ok = method2($u) if $ok; my $pid = open my $ph, "/somewhere/program $v |"; my $output = ''; $ok = method3(<$ph>, \$output) if $ok; close $ph; waitpid $ph,0; if ($ok) { somelogger(5, "fred", "fred completed successfully"); } else { somelogger(5, "fred", "error during fred"); } return $ok; }
      or maybe even (assuming the methods can be made to return error strings or the empty string for no error)
      sub fred { my ($t, $u, $v, $w, $x, $y) = @_; somelogger(5, "fred", "start of fred"); my $err; $err = method1($t) unless $err; $err = method2($u) unless $err; my $pid = open my $ph, "/somewhere/program $v |"; my $output = ''; $err = method3(<$ph>, \$output) unless $err; close $ph; waitpid $ph,0; if ($err) { somelogger(5, "fred", "error '$err' during fred"); } else { somelogger(5, "fred", "fred completed successfully"); } return $err; }


      Give a man a fish:  <%-(-(-(-<

      1) avoiding excessive nested blocks in terms of length and depth, 2) having a single point of return or exit from a routine or subroutine and 3) avoiding goto.

      That's why Larry created subroutines.

      And (2) is just a stupid restriction. Adding extra returns is one of the most effect refactoring tools I found.

      - tye        

        ... subroutines ... extra returns ...

        I don't understand these points.

        Certainly using multiple returns and/or refactoring code into subroutines can, in general, be extremely useful for improving the readability/reliability/maintainability of code.

        But the particular code example presented in Re: Number of times I've used goto in Perl has a rather unusual structure. There are two interleaved streams of function calls and instructions:

        • optional functions that may be called only if no previous optional function failed;
        • required function calls and instructions that must all be called in order even if any previous optional function call has failed.

        Using multiple returns and/or refactoring into subroutines (or even (shudder) using nested if-elsif-else blocks or conditional goto statements), it would certainly be possible to replicate the control flow of the OPed code, but again, I can't see how it would be any improvement on anonymized user 468275's basic approach; indeed, it seems to me that it could only be much worse. Can you give an example of what you envision?


        Give a man a fish:  <%-(-(-(-<

        Adding extra returns makes it much more time-consuming for someone who didn't write the code to figure out what the return value of a routine is or means. (It also means extra code if you're using any debugging tools to check assertions or track runtime with code that executes at the start and end of important routines. Which I always do in Perl, because Perl has so little typing.)

        In fact, about the only time I use goto is to goto the exit point of a routine. The necessary label will notify anyone looking at that code that there is some internal path directly to it.

View List Of Past Polls


Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (1)
As of 2024-04-18 23:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found