[Chicago-talk] DEBUG function

Steven Lembark lembark at wrkhors.com
Mon Mar 1 00:11:14 CST 2004

> obviously this is debugging stuff.  My question is how would you ever get
> DEBUG to return "true", in order to enter the debugging code?  I know you
> can always change the source to make:
> sub DEBUG () { 1 }

You answered it.

> But is there some way you are supposed to do this at runtime?

Subs with empty prototype and constant return are inlined
at compile time (see the inline module). Basically this is
an attempt at the old C hack for sectioning out code:

	#if 0
		/* code not compiled */

I don't know if the compiler will optimize out the literal
zero in a conditional and thus drop the if logic out of its
generated code. In any case, the inlining bypasses the symbol
table, so there is no way to update the call to something else
at runtime.

An alternative -- based on low overhead for sub calls in
perl -- is to use debug sub's (possibly in a separate module)
and set them after checking command lines or $^P:

	# default for debugging is off.

	my $debug_foo = sub () {};
	my $debug_bar = sub () {};


	GetOptions $cmdline, @valid or die "trying...";

	$debug_foo = \&My::Debug::Module::foo_debugger
			if $cmdline->{debug_foo};

	$debug_bar = \&My::Debug::Module::foo_debugger
			if $cmdline->{debug_bar};


	# low overhead NULL call unless the command
	# line includes --debug_foo.

	$debug_foo->( 'Your message here' );

This is the moral equivalent of

	#ifdef DEBUG_FOO
		#define debug_foo (void *)NULL;
		#define debug_foo( char *arg1, char *arg2 ) { ... }

	#ifdef DEBUG_BAR

in C.

You can also update the symbol table if you don't like using
$debug_foo->() for your debug call:

	sub debug_foo (){}


	if( $cmdline->{debug_foo} )
		my $sub = My::Debug::Module->can('foo_debugger')
			or die "Bogus debugger: My::Debug::Module cannot 'foo_debugger'"
		*debug_foo = $sub

Nice thing about the can operator is the extra sanity check
for an existing foo debugger before assigning garbage to a
handler. Assigning the reference into the sub's glob resets
the subroutine at runtime.

Using a separate module of debug calls also helps clean
up the main module, since most users have no interest
in how the debug code itself works. With the "if DEBUG
&& ..." syntax you have to read through all of the debug
sub syntax when perusing the source.

Steven Lembark                               2930 W. Palmer
Workhorse Computing                       Chicago, IL 60647
                                            +1 888 359 3508

More information about the Chicago-talk mailing list