Elizabeth Mattijsen


ifdef - conditionally enable text within pod sections as code


  export DEBUGGING=1
  perl -Mifdef yourscript.pl


  perl -Mifdef=VERBOSE yourscript.pl


  perl -Mifdef=all yourscript.pl


  ======= yourscript.pl ================================================

  # code that's always compiled and executed

  =begin DEBUGGING

  warn "Only compiled and executed when DEBUGGING or 'all' enabled\n"

  =begin VERBOSE

  warn "Only compiled and executed when VERBOSE or 'all' enabled\n"


  # code that's always compiled and executed

  # BEGINNING compiled and executed when BEGINNING enabled



The "ifdef" pragma allows a developer to add sections of code that will be compiled and executed only when the "ifdef" pragma is specifically enabled. If the "ifdef" pragma is not enabled, then there is no overhead involved in either compilation of execution (other than the standard overhead of Perl skipping =pod sections).

To prevent interference with other pod handlers, the name of the pod handler must be in uppercase.

If a =begin pod section is considered for replacement, then a scope is created around that pod section so that there is no interference with any of the code around it. For example:

 my $foo = 2;


 my $foo = 1;
 warn "debug foo = $foo\n";


 warn "normal foo = $foo\n";

is converted on the fly (before Perl compiles it) to:

 my $foo = 2;


 my $foo = 1;
 warn "foo = $foo\n";


 warn "normal foo = $foo\n";

But of course, this happens only if the "ifdef" pragma is loaded and the environment variable DEBUGGING is set.

As a shortcut for only single lines of code, you can also specify a single line of code inside a commented line:

 # DEBUGGING print "we're in debugging mode now\n";

will only print the string "we're in debugging mode now\n" when the environment variable DEBUGGING is set. Please note that the 'all' flag is ignored in this case, as there is too much standard code out there that uses all uppercase markers at the beginning of an inline comment which cause compile errors if they would be enabled.


One day, I finally had enough of always putting in and taking out debug statements from modules I was developing. I figured there had to be a better way to do this. Now, this module allows to leave debugging code inside your programs and only have them come alive when you want them to be alive. Without any run-time penalties when you're in production.


 Filter::Util::Call (any)
 IO::File (any)


This version is completely written in Perl. It uses a source filter to provide its magic to the script being run and an @INC handler for all of the modules that are loaded otherwise. Because the pod directives are ignored by Perl during normal compilation, the source filter is not needed for production use so there will be no performance penalty in that case.


Overhead during development

Because the "ifdef" pragma uses a source filter for the invoked script, and an @INC handler for all further required files, there is an inherent overhead for compiling Perl source code. Not loading ifdef.pm at all, causes the normal pod section ignoring functionality of Perl to come in place (without any added overhead).

No changing of environment variables during execution

Since the "ifdef" pragma performs all of this magic at compile time, it generally does not make sense to change the values of applicable environment variables at execution, as there will be no compiled code available to activate.

Modules that use AutoLoader, SelfLoader, load, etc.

For the moment, these modules bypass the mechanism of this module. An interface with load.pm is on the TODO list. Patches for other autoloading modules are welcomed.

Doesn't seem to work on mod_perl

Unfortunately, there still seem to be problems with getting this moduled to work reliably under mod_perl.


The following subroutines are available for doing your own processing, e.g. for inclusion in your own AUTOLOADing modules. The subroutines are not exported: if you want to use them in your own namespace, you will need to import them yourself thusly:

 *myprocess = \&ifdef::process;

would import the "ifdef::process" subroutine as "myprocess" in your namespace..


 ifdef::process( $direct );

 $processed = ifdef::process( $original );

The "process" subroutine allows you process a given string of source code and have it processed in the same manner as which the source filter / @INC handler of "ifdef.pm" would do.

There are two modes of calling: if called in a void context, it will process the string and put the result in place. An alternate method allows you to keep a copy: if called in scalar or list context, the processed string will be returned.

See "oneline" of you want to process line by line.



The "reset" subroutine is needed only if you're doing your own processing with the "oneline" subroutine. It resets the internal variables so that no state of previous calls to "process" (or the internally called source filter or @INC handler) will remain.



The "oneline" subroutine does just that: it process a single line of source code. The line of source to be processed is expected to be in $_. The processed line will be stored in $_ as well. So there are no input or output parameters.

See "process" of you want to a string consisting of many lines in one go.


If you want to find out how this module is appreciated by other people, please check out this module's rating at http://cpanratings.perl.org/i/ifdef (if there are any ratings for this module). If you like this module, or otherwise would like to have your opinion known, you can add your rating of this module at http://cpanratings.perl.org/rate/?distribution=ifdef.


Nick Kostirya for the idea of activating single line comments.

Konstantin Tokar for pointing out problems with empty code code blocks and inline comments when the "all" flag was specified. And providing patches!


Elizabeth Mattijsen, <liz@dijkmat.nl>.

Please report bugs to <perlbugs@dijkmat.nl>.


Copyright (c) 2004 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.