#!/usr/local/bin/perl -w use strict; no strict 'refs'; use vars qw( $opt_m $opt_M ); package A; use Data::Dumper; use vars qw($AUTOLOAD); my %cache; use Carp 'cluck'; use optimizer extend => sub { my $name = $_[0]->name(); cluck "dump ", Dumper \@_ if 0 or $name eq "goto" # or $name eq "print" or ref $_[0] =~ /CV/i ; # =~ /__ANON__/; }; sub AUTOLOAD { # Use an extension of the default optimizer (my $meth = $AUTOLOAD) =~ s/.*:://; return if $meth eq 'DESTROY'; my ($package, $filename, $line, $subroutine) = caller(0); my $cat = join '_', $meth, $package, $filename, $line; $cat =~ s|[\./:]||g; my $code; unless (exists $cache{$cat}) { $code = sub { shift @_; print " calling <$meth> ",$cat," (@_)\n" }; print "creating <$meth> $cat\n"; $cache{$cat} = $code; *{'A::'.$cat} = $code if $main::opt_m; # vivify specific-usage name *{'A::'.$meth} = $code unless $main::opt_M; # vivify generic name } else { # runs when munging $code = $cache{$cat}; print "fetching: $cat\n"; } goto &$code; } package main; use Getopt::Std; getopts('mM') or die <debug('aval'); A->info('another'); A->info('now that info() is built, the line numbers wrong.'); A->info('more importantly, this call needs its own handler, not the other one.'); A->something('anything'); A->other('anything'); } } __END__ =head1 extending Log::Log4perl package Log::Log4perl::AutoCategorize # notional extension Log::Log4perl provides a flexible logging system which allows configuration of one or more output streams, each collecting messages from a set of logging-categories / sources. Id like to extend it by coupling the logging-category to caller() info, following benefits accrue; 1. END{} handler can report on Logger coverage. 2. scope friendly filtering, 3. well, 2 is something.. =head1 my code Im using AUTOLOAD to implement A->$invoke(), for all values of $invoke; Ill eventually delegate them to Log::Log4perl->debug(), info(), warn(), or error(), dependent upon config. AUTOLOAD uses caller() to make and test the logging-category, and would either write a log entry, or just return. That yes/no decision can result in a noop, or an appropriate print to stream. method-munging guarantees that each $invoke() is lexically unique (file & line, approx), and carries context for purposes of logging and filtering. But once name is munged, its not accessible by original calling point, and AUTOLOAD must regenerate the munged-name to look up the cached coderef. =head1 SYNOPSIS - Desired # assuming a package like this use Log::Log4perl::AutoCategorize ( alias_as => 'Logger' ); sub doit { ... # want simple invocations, like this Logger->debug(@_); # to really mean Logger->debug_<$callerpkg,$caller_sub,$caller_ln> (@_); # its really a macro }