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

Hey monks

In the code below, I'm wondering if 'last' is redundant if the call to the subroutine msg includes an 'exit'.
my @array = qw(hey hello yes no key dog cat); foreach (@array) { if (/key/) { msg('Yes, key found'); last; # is 'last' redundant here?? } } sub msg { my ($msg) = @_; print "$msg\n"; exit; }
Looking forward to hear from ya =)

2004-04-07 edit by ybiC - retitle from "Is 'last' redundant?"

Replies are listed 'Best First'.
Re: Is 'last' redundant?
by PodMaster (Abbot) on Apr 07, 2003 at 12:53 UTC
    Yes it is. On the other hand, I wouldn't structure my program in such a way. I'd personally do something like
    foreach (@bar){ if(/foo/){ msg("bar bar"); last; } } exit(); sub msg { print "@_\n"; }
    If you're wondering why, see BrowserUks reply -- he completely missed that a function called msg exit's the program, which is quite a weird thing for a function called msg to do ;)


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
    ** The Third rule of perl club is a statement of fact: pod is sexy.

Re: Is 'last' redundant?
by broquaint (Abbot) on Apr 07, 2003 at 12:51 UTC
    I'm wondering if 'last' is redundant if the call to the subroutine msg includes an 'exit'.
    It is indeed redundant as it will never be reached, and I wouldn't be surprised if it was optimised out (see. Aristotle's reply on why this can't be done). It could be seen as self-documenting code, but it could be somewhat misleading and msg() should be documented denoting the fact that it exit()s when called. In fact, it looks a little like die(), so you might just want to use that instead e.g
    foreach (@array) { die "Yes, key found\n" if /key/; }

    HTH

    _________
    broquaint

    update: extraneous semi-colon encountered a Backspace

      Back when I used to write a lot more C than I do now, I adopted the practice that if a function is not going to return, its name should have an and_die at the end, unless it's very obvious that it's not going to return (e.g. functions called "fatal", "die", or similar) This makes it impossible to miss. Of course, gcc also has some function attributes you can set that help the compiler optimize more in the case of never-returning functions..

      That cannot be optimized away. The compiler can't know what's going to happen at runtime - among others, things like overriding exit or msg..

      Note that you have an extraneous semicolon, btw.

      Makeshifts last the longest.

Re: Is 'last' redundant?
by Abigail-II (Bishop) on Apr 07, 2003 at 13:09 UTC
    Normally, it is redundant. I don't think there's any possibility for an exit to fail, but I don't have Stevens handy at the moment, so I cannot check. Of course, if there's any posibility the msg subroutine gets redefined, it's not redundant.

    While I would be hesitant to put a call to exit in a subroutine (but I have done it in the past), I certainly wouldn't be eagar to remove the 'redundant' last. It gives a clue that after finding key, the array isn't searched any further.

    Abigail

Re: Is 'last' redundant?
by cLive ;-) (Prior) on Apr 07, 2003 at 12:57 UTC
    how long would it have taken you to change the 'last' to a print "needed" statement and running the code once with 'key' in the array, and once without.

    Please read this

    .02

    cLive ;-)

      cLive, thanks! see, it didn't occur to me to test with a print statement. it's definitely not in my interest to waste anybody's time or waste words =)
Re: Is 'last' redundant in this code?
by dws (Chancellor) on Apr 07, 2003 at 17:38 UTC
    I'm wondering if 'last' is redundant if the call to the subroutine msg includes an 'exit'.

    In the small snippet you've shown, and assuming that it's not an extract from a larger program, it wouldn't take too long for a reader with basic Perl skills to untangle what you mean, though they might puzzle over why you wrote "last;" instead of "exit;", and therein lies a problem: Whenever you leave something in your code that a later reader is going to puzzle over, you increase the risk of them breaking the code if they have to change it.

    A cleaner way to handle this, as previously mentioned, is to lift the "exit;" out of msg(), and either replace the "last;" with "exit;" or put the exit at the bottom of the loop. Either of these removes a source of confusion.

    Consider how unambiguous it is to write:

    my @array = qw(hey hello yes no key dog cat); foreach (@array) { if (/key/) { msg('Yes, key found'); exit; } } sub msg { my ($msg) = @_; print "$msg\n"; }
    There's no mistaking your intent.

      The other sane alternative, of course, is to get rid of the last after renaming the function to exit_with_msg.

      Makeshifts last the longest.

Re: Is 'last' redundant?
by strfry() (Monk) on Apr 07, 2003 at 13:59 UTC
    looking at your code, it appears that it would stop looking for "key" after it's found it the first. if you only intend on reporting the first instance of "key" in an array, and you think there's a chance in hell that there will ever be another instance of "key" in your array, then no, it's not redundant. (:

    this is asssuming, of course, that you intend to use this code on something more complex, that may contain more than one instance of whatever you're searching for.

    strfry(reality)
Re: Is 'last' redundant?
by BrowserUk (Patriarch) on Apr 07, 2003 at 12:51 UTC

    Update: Er. Whoops!

    No. Without the last statement, the loop would iterate twice more ('cat' & 'dog') than it needs to. For such a small dataset as shown, the difference is minimal, but if the dataset were large, and the key found early, then a significant saving results by short circuiting the loop.


    Examine what is said, not who speaks.
    1) When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
    2) The only way of discovering the limits of the possible is to venture a little way past them into the impossible
    3) Any sufficiently advanced technology is indistinguishable from magic.
    Arthur C. Clarke.