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.