use Attribute::Handlers; use vars qw($DEBUG); $DEBUG = 0; use constant { PKG => 0, SYMBOL => 1, CODE => 2, ATTR => 3, DATA => 4, PHASE => 5, }; sub Debug :ATTR { my ($symbol, $code, $level) = @_[SYMBOL, CODE, DATA]; $level = $level ne '' ? $level : $DEBUG ; my $name = join '::', *{$symbol}{PACKAGE}, *{$symbol}{NAME}; no warnings 'redefine'; *{$symbol} = sub { my @output = $code->(@_); if ( $level >= 2 ) { warn sprintf "DEBUG: entering %s(%s)\n", $name, ($level >= 3 ? "@_" : ''); } return @output; }; } sub somesub :Debug { # Do something. } sub othersub :Debug(3) { # Do some other thing. } #### $level = $level ne '' ? $level : $DEBUG ; #### $level ||= $DEBUG;