Tom's Tom's - 1 year ago 86
Perl Question

Perl way of execute/ignore code (like assert in C)

I'm a real beginner in Perl programming (v 5.20.2 on Debian 8) and I'm looking to a way of implementing a "debugging" with no overhead at Perl execution-time when I don't need to debug.

In C, we can do that with

and the
gcc option (and in general, you can do your own assert by following the same way with your own define constante like

Well, first idea is simply to set a global variable
and test again it, but it will generate a bunch of useless test when I will don't want to be in debug mode.

There are CPAN Module like assertions or Carp::Assert, but it's seem that there will be an if test even when I don't want debugging.

Is there a Perl way for deactivate portion of code depending on "something"?

Bonus question: I want to make a Perl module with the same functionality, so if there is a way to say "enable/disable debugging" when I do the
use MyModule
, well, I will be a happy Perl developer.

Answer Source

Perl does not have that built-in. There is also no compiling happening like in C because Perl is an interpreted language. The fact that Carp::Assert exists (and is written by someone who is involved in the Perl core) is a pretty good assertion (pun intended) that this feature is not there in Perl directly.

In general, a couple of if DEBUG or if $debug or similar are not big deal. Computers today are so fast that those operations hardly matter unless you have them in a loop that gets called millions of times, or you have extremely time-critical code. In your average program, you can ignore that overhead.

In fact perl1 will optimize those out if you use a constant. Consider this program.

use constant DEBUG => 1;
print "stuff" if DEBUG;

If run with B::Deparse, it will produce the following output.

$ perl -MO=Deparse 
use constant ('DEBUG', 1);
print 'stuff'; syntax OK

There's our print statement. But if you turn the DEBUG constant to 0 and run the same command, you get something else.

$ perl -MO=Deparse 
use constant ('DEBUG', 0);
'???'; syntax OK

As you can see, the print is gone. All that remains is '???';, which is a NOOP.

Let's run the same thing with B::Concise. First, with DEBUG turned to 0.

$ perl -MO=Concise 
3  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 120 v:{ ->3
-     <0> ex-const v*/4,FOLD ->3 syntax OK

And then with DEBUG set to 1.

$ perl -MO=Concise 
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 120 v:{ ->3
5     <@> print vK/FOLD ->6
3        <0> pushmark s ->4
4        <$> const(PV "stuff") s ->5 syntax OK

As you can see, there are more operations. The print "stuff" if DEBUG is in fact optimized out. This is pretty much the same thing as what you describe in your C example.

Go ahead and try out with those two modules to see if it behaves the same when using Carp::Assert.

If you don't like that, take a look at Smart::Comments. It introduces comment syntax that get executed when you use it. That's pretty cool, because those can just sit around and not do stuff when you don't load the module.

use Smart::Comments;

my $var = suspect_value();

### $var

There is also Devel::Comments, which seems to do the same.

1) perl with a small p is the interpreter program, not the language

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download