http://www.perlmonks.org?node_id=966851

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

Hi

For a package which I'm coding I wanna offer to switch on debugging by a constant!

The idea is that the related code is not compiled if the flag is false (codefolding)¹ thus not causing performance lost if in non-debug mode.

Is there any way to tell use constant which namespace to use?

ATM I'm using something like

# --- user's code package MyPackg; use constant DBG => 0; package main; ... MyPackg::func(); ... # --- my code package MyPackg; sub func { print "DEBUGGING" if DBG; # won't be compiled }
Any nicer way to achieve this?

Cheers Rolf

UPDATE: at least it can be simplified for the user with lexically scoped packages:
{ package MyPackg; use constant DBG => 0; }
UPDATE: ¹) better phrased as "unreachable code removal"

Replies are listed 'Best First'.
Re: defining constant in other package
by Anonymous Monk on Apr 24, 2012 at 14:30 UTC
    No there isn't, but a constant is merely
    sub Ro:Sham::Bo::DEBUG(){ !!1 } sub Ro:Sham::Bo::DEBUG(){ !!0 } package Ro:Sham::Bo; use constant DEBUG => !!$ENV{PERL_RO_SHAM_BO};
      *sigh* if using the ENV option it should be
      package Ro:Sham::Bo; use constant DEBUG => !!$ENV{PERL_RO_SHAM_BO_DEBUG};
      Well but even when putting a sub-declaration into a BEGIN block codefoldinmg isn't effected!

      > perl -MO=Deparse tst.pl sub BEGIN { sub MyPackg::DBG { 0; } } our $a = 1; package MyPackg; print 'DEBUGGING' if DBG(); # <-- oops print 'huhu'; tst.pl syntax OK

      OK forget it this works, thanks!

      BEGIN { sub MyPackg::Debug {!!0}; } our $a=1; package MyPackg; use constant DBG => MyPackg::Debug; print "DEBUGGING" if DBG; # won't be compiled print "huhu";

      > perl -MO=Deparse tst.pl sub BEGIN { sub MyPackg::Debug { 0; } } our $a = 1; package MyPackg; sub BEGIN { require constant; do { 'constant'->import('DBG', Debug()) }; } '???'; print 'huhu'; tst.pl syntax OK

      Cheers Rolf

        Perl wants a constant (subroutine) to have an empty prototype before it eliminates code guarded by it:

        BEGIN { sub MyPackg::DBG() { 0; } } our $a = 1; package MyPackg; print 'DEBUGGING' if DBG(); # <-- oops print 'huhu';

        gives this output:

        F:\>perl -MO=Deparse tmp.pl sub MyPackg::DBG () { 0 } sub BEGIN { } our $a = 1; package MyPackg; '???'; print 'huhu'; tmp.pl syntax OK
Re: defining constant in other package
by jandrew (Chaplain) on Apr 24, 2012 at 15:40 UTC
      Thanks, but no thanks. :)

      Better no source filter in productive code!

      Smart::Comments may be OK if the developper tests his own code, but in this case the user should have the option to ask for additional infos (like benchmarks).

      Cheers Rolf

Re: defining constant in other package
by BillKSmith (Monsignor) on Apr 24, 2012 at 22:20 UTC
    As a side issue, I would always prefer to see Readonly rather than constant. The resulting structure is syntactically a variable rather than a function. The biggest advantage is that it interpolates in a string the same as any other variable.
      Readonly can be used for constant folding?

      Cheers Rolf

        I am not sure what you mean by "constant folding." Perl ensures that "variables" marked as readonly cannot be used as l-values. I doubt that they are special in any other way.