in reply to How to turn a "developer code" into a "user code"

Rather than using a variable, use a constant.

use constant I_AM_DEV => 1;

A proper constant lets the Perl compiler optimize away the devepment code when it is switched off - i.e. it runs faster.

Replies are listed 'Best First'.
Re^2: How to turn a "developer code" into a "user code"
by mascip (Pilgrim) on Mar 11, 2012 at 16:28 UTC

    i do

    use Readonly 1.03; [...] Readonly my $I_AM_DEV => $FALSE;
    Is it equivalent to what you wrote ?

      No, using constants allows the Perl debugger to specifically ignore blocks of your code - it can figure out which parts it can ignore at compile-time, and avoid even compiling them. Take for example this script:

      use constant DEBUG => 0; if (DEBUG) { print "Calculator with debugging..."; } else { print "Calculator..."; } print "1 + 1 = ", (1 + 1), "\n";

      If you save that as, say debug.pl and then run the following command:

      perl -MO=Deparse tmp/constants.pl

      This uses the B::Deparse module to show you the code that Perl's runtime will actually execute. The result is:

      use constant ('DEBUG', 0); do { print 'Calculator...' }; print '1 + 1 = ', 2, "\n";

      You will notice that the print "Calculator with debugging..." part is entirely absent, because the Perl compiler knows that DEBUG is false, so that chunk of code will never be run! Perl doesn't bother compiling it. Even the if/else structure has gone.

      (You'll notice also that the Perl compiler has added 1+1 so that the Perl runtime doesn't have to. This is called constant folding. In this particular example it doesn't offer any real benefit, but if that sum was inside a loop, then calculating it once at compile time is much better than calculating it every loop at runtime!)

      So anyway, using constants for tasks like this allows the Perl compiler to optimize your code. With variables it can't.

      So what about variables that have been set using Readonly?

      use Readonly; Readonly my $DEBUG => 0; if ($DEBUG) { print "Calculator with debugging..."; } else { print "Calculator..."; } print "1 + 1 = ", (1 + 1), "\n";

      Running it through B::Deparse we get...

      use Readonly; Readonly my $DEBUG, 0; if ($DEBUG) { print 'Calculator with debugging...'; } else { print 'Calculator...'; } print '1 + 1 = ', 2, "\n";

      So the compiler has not been able to do much optimisation.

      Also it's worth noting that Readonly is implemented using Perl's tied variable magic, which imposes a considerable performance penalty - Readonly variables are actually slower than normal variables.

        Great explanation, thank you !
        I guess Readonly is not that useful for scalars, then; but better used for arrays and hashes.