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...

Replies are listed 'Best First'.
Re: Functions that know which package they've been exported to.
by BrowserUk (Patriarch) on Jan 24, 2012 at 09:19 UTC

    That seems like an obscure and complicated way of achieving something simple:

    MyLogger.pm:

    package MyLogger; require Exporter; our @ISA = qw[ Exporter ]; our @EXPORT = qw[ logMessage ]; sub logMessage { print STDERR caller() . '::' . shift(); }

    MyScript.pl

    #! perl -slw use strict; package MyScript; use MyLogger; logMessage( 'hello' ); package main; use MyLogger; logMessage( 'hello' );

    Outputs:

    c:\test>MyScript.pl MyScript::hello main::hello

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      No, caller in the logMessage function itself does something different. Witness:

      { package My::Logger; sub import { my $PACKAGE = caller; no strict 'refs'; *{"$PACKAGE\::log_message"} = sub { my ($message) = @_; print STDERR "$PACKAGE - $message"; }; } } { package My::Utils; My::Logger->import; } { package main; # outputs "My::Utils - Hello", not "main - Hello" My::Utils::log_message("Hello"); }

      The log_message function outputs what package it has been installled into, not called from.

      While this is rarely useful, it does occasionally have uses. Object::Stash uses something along these lines.

        Okay. I can't quite see the use for it, but I do now see the difference.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?