I'll add some more stuff here soon.
Sometimes you want to write a function that knows which package it has been exported to. For example:
{ package My::Logger; our @EXPORT = qw/log_message/; use parent qw/Exporter/; sub log_message { my ($message) = @_; print STDERR "$PACKAGE - $message"; } } { package My::Script; # if these were separate files, we'd use "use My::Logger" My::Logger->import; # want this to say "My::Script - Hello" log_message("Hello"); }
This is not that difficult to do. It just requires writing a custom import function which pulls some funny tricks with closures...
{ package My::Logger; sub import { my $PACKAGE = caller; no strict 'refs'; *{"$PACKAGE\::log_message"} = sub { my ($message) = @_; print STDERR "$PACKAGE - $message"; }; } } { package My::Script; My::Logger->import; log_message("Hello"); }
Random additional notes...
With *{"$PACKAGE\::log_message"} = sub {...} beware that if $PACKAGE uses namespace::autoclean or something similar, the function log_message will get cleaned away. (The same happens with functions exported by Exporter - the behaviour is not only intentional, but kinda the whole point of namespace::autoclean.) If you want to avoid your function getting swept away, then use Sub::Name:
use Sub::Name qw/subname/; do { no strict 'refs'; my $name = "$PACKAGE\::log_message"; *{$name} = subname $name => sub { ... }; };
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |