Damian Conway <[EMAIL PROTECTED]> writes: > John Siracusa asked: > >> Has there been any discussion of how to create code in Perl 6 that's there >> under some conditions, but not there under others? I'm thinking of the >> spiritual equivalent of #ifdef, only Perlish. >> In Perl 5, there were many attempts to use such a feature for >> debugging and >> assertions. What everyone wanted to do was write code like this: >> debug("Doing foo with $bar and $baz"); >> foo($bar, $baz); >> And then have the entire call to debug() just plain disappear when >> the >> program was run with a certain flag, or when a particular constant was set, >> or whatever. The closest we got in Perl 5, AFAIK, was stuff this: >> use constant DEBUG => 0; >> ... >> debug("Doing foo with $bar and $baz") if DEBUG; >> foo($bar, $baz); >> But all those "if DEBUG"s or "DEBUG &&"s were a pain. So I'm >> wondering what >> the solution will be in Perl 6. > > Something like this: > > module Debug; > > my $debugging = 1; > > method import ($debug) { $debguuging = $debug } > > sub debug is immediate is exported (@message) { > return $debugging ?? { print $*STDERR: @message; } :: {;} > } > > then: > > use Debug; > > debug("Doing foo with $bar and $baz"); > > and to deactivate the debug statements: > > use Debug 0; > > debug("Doing foo with $bar and $baz"); > > > "Immediate" subroutines are executed as soon as they are parsed (i.e. they're > like named BEGIN blocks). > > Returning a closure/block from an immediate sub called in a void context > (as C<debug> is in the example above) causes the immediate sub call to be > replaced -- during compilation! -- by the returned closure/block.
So, one could implement 'assert' in the same package with something like: sub assert is immediate is exported ( rx/<expr>/ &expr ; $message = "Assertion failed " ) { return $debugging ?? { &expr() || die $message } :: { ; } } For bonus points one could have the assertion die if it's called in a non void context, but I'll leave that as an exercise for the interested reader.