package Dsay; use warnings; use strict; use feature qw{ say }; use experimental qw( signatures ); use Scope::Guard qw{ guard }; use Exporter qw{ import }; our @EXPORT = qw( %debug set_darea get_darea dsay ); our %debug; my $d_area = '(default)'; # Not ours anymore! sub set_darea($value) { my $old_value = $d_area; $d_area = $value; return guard { $d_area = $old_value } } sub get_darea() { $d_area } # Etc. #### sub common_sub { say 'call to common sub (d_area is ', get_darea(), ')'; dsay "debugging output from common_sub"; } sub one { say "call to one:"; my $_scope = set_darea('one'); dsay "debugging output from one"; common_sub; dsay "more debugging output from one"; } sub two { say "call to two:"; my $_scope = set_darea('two'); dsay "debugging output from two"; common_sub; dsay "more debugging output from two"; } #### Can't create a Scope::Guard in void context #### use Dsay; package Dsay; our $d_area; package main; #### *d_area = *Dsay::d_area; #### use Exporter; our @EXPORT = qw( %debug dsay $d_area ); our %debug; our $d_area = "(default)"; sub import { my $caller = caller; no strict 'refs'; *{ $caller . '::d_area' } = *Dsay::d_area; goto &Exporter::import } #### use Exporter qw{ import }; our @EXPORT = qw( %debug %opt dsay ); our %debug; our %opt = (d_area => "(default)"); sub dsay( @args ) { return unless $debug{ uc $opt{d_area} } || $debug{'ALL'}; my $prefix = $opt{d_area} ne "(default)" ? "DEBUG $opt{d_area}: " : "DEBUG: "; say $prefix, @args; } #### sub one { say "call to one:"; local $opt{d_area} = "one"; dsay "debugging output from one"; common_sub; dsay "more debugging output from one"; } # Etc. #### *{"${callpkg}::$sym"} = $type eq '&' ? \&{"${pkg}::$sym"} : $type eq '$' ? \${"${pkg}::$sym"} : $type eq '@' ? \@{"${pkg}::$sym"} : $type eq '%' ? \%{"${pkg}::$sym"} : $type eq '*' ? *{"${pkg}::$sym"} : do { require Carp; Carp::croak("Can't export symbol: $type$sym") }; #### *{ $caller . '::d_area' } = 'Dsay::d_area'; #### *{"${callpkg}::$sym"} = "${pkg}::$sym" if '$' eq $type;