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

Hi All

I don't know how perl pre-parses code on the fly - is it quicker (i.e. will perl map out a call to a sub-routine on pre-parse) such as


sudo code if ($debug == "true") { &debugit; # call the routine } or if ($debug == "true") { ** do all the debug code here and/or carry on ** }

Thanks,

Nick

Replies are listed 'Best First'.
Re: Embedded function or subroutine - which is better?
by afoken (Chancellor) on Aug 27, 2016 at 17:04 UTC
    I don't know how perl pre-parses code on the fly - is it quicker (i.e. will perl map out a call to a sub-routine on pre-parse) such as
    if ($debug == "true") { &debugit; # call the routine }
    or
    if ($debug == "true") { ** do all the debug code here and/or carry on ** }

    Premature optimization. Keep the code readable and maintainable. If you need the debug code more than once, put it in a function. If the debug code spans more than a few lines, do the same. For a single, simple print, wrap it directly in the if block.

    Oh, and by the way: Omit the ampersand in function calls. It is perl4-style and does not do what you expect. See also Re^2: Merge log files causing Out of Memory (just a note on ampersand).

    Another update: $debug == "true" does not do what you want. == is for numeric compares, eq is for string compares. (how to remember that). But you don't want either, use Perl's native booleans: In boolean context, scalars that are undefined (undef), the empty string ("") or the number zero (0) evaluate as false, any other value evaluates as false true. Commonly, you would use the value 1. So:

    my $debug=1; # or $debug='' to disable # later: if ($debug) { debugIt(); }

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Blimey!, as we say here in England.

      I just re-read about sub routines in my Camel book, and have never ever heard about omitting the & - just a 'subroutine();' does it!

      I just changed my code to have a sub debug; and it works great and seems more fluid!

      Many thanks for your wisdom!

      Regards, Nick

      P.S. sorry, was replying then saw your update - the '==' was a mistake by me just typing in from a bad memory - should be 'eq' of course!

      Thanks again. The line '$debug eq "true"' is a must as it comes from a HTML form and can have different string values, so a match is needed.

      Nick

Re: Embedded function or subroutine - which is better?
by AnomalousMonk (Archbishop) on Aug 27, 2016 at 17:40 UTC
    I don't know how perl pre-parses code on the fly ...

    You can let Perl tell you how it parses your code; see O and B::Deparse.

    c:\@Work\Perl\monks>perl -wMstrict -MO=Deparse,-p -le "use constant DEBUG => 1; ;; DEBUG and debugIt(); ;; sub debugIt { print 'debugging it'; } " BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use constant ('DEBUG', 1); use strict 'refs'; debugIt(); sub debugIt { use strict 'refs'; print('debugging it'); } -e syntax OK c:\@Work\Perl\monks>perl -wMstrict -MO=Deparse,-p -le "use constant DEBUG => 0; ;; DEBUG and debugIt(); ;; sub debugIt { print 'debugging it'; } " BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use constant ('DEBUG', 0); use strict 'refs'; '???'; sub debugIt { use strict 'refs'; print('debugging it'); } -e syntax OK
    The  '???' deparser placeholder flags the non-compilation of an unreachable statement (update: or expression?).

    Update:
        if (DEBUG) { debugIt(); }
    and
        debugIt() if DEBUG;
    would be other variations you might use. Of course, prefer
        if (DEBUG) { more(); than(); one(); statement(); }
    for, well, more than one statement.


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

Re: Embedded function or subroutine - which is better?
by Marshall (Canon) on Aug 27, 2016 at 22:01 UTC
    AnomalousMonk++ stuck an important point in his post that you might have missed the significance of.

    use constant DEBUG => 1; do_debug() if DEBUG;
    This "constant" pragma is a cool thing. If DEBUG => 0;, Perl will realize that do_debug() if DEBUG; is never going to do anything at all, could never be executed and therefore won't even compile anything into the code. So you can leave a bunch of debug stuff in the production code without incurring any run time penalty at all in the non-debug case. I typically use ALLCAPS for constants like this. It is easier for me to spot them in the code.

    So, in the context of your post, there can't be anything faster than doing nothing at all in the non-debug case. Also often in my debug code, usually some sort of I/O operation is going to happen which is so slow that whether it is in a subroutine or not makes absolutely no difference in the scheme of things.

    update: Usually instead of just "do_debug()", I put some name on that subroutine like perhaps "dump_decision_tree() if DEBUG;". I do that even if this debug code could only be called once. The name of the sub tells me what it would do without having to look further. I don't have to skip past "inline" debug code. I usually do that for anything more than a simple "print".

Re: Embedded function or subroutine - which is better? *UPDATE*
by Linicks (Scribe) on Aug 28, 2016 at 10:59 UTC

    OK, thanks all. After enlightenment I have found a decent solution

    As the requirement comes from an HTML form (returns '1' if ticked), the code I am now using to call the function is thus:

    debug() if $request{'debug'};

    Short and sweet :)

    Nick