Perl6::Caller

Ovid on 2007-04-21T19:36:34

Update 1: Oops. Seems that Christian Lembark has the permission rights to the caller namespace. Working around that now.

Update 2: Turns out that he has a 'package caller' declaration in his FindBin::libs module. Thus, he owns that namespace.

I've just uploaded Perl6::Caller. If you read this and it's not on the CPAN, just wait a few hours. Feedback and bug reports gratefully accepted. I had to do a couple of weird things to get it to work and I decided that, at least for the first release, to not allow optional overriding of CORE::GLOBAL::caller. Relevant docs:

NAME
    Perl6::Caller - OO "caller()" interface

VERSION
    Version 0.01

SYNOPSIS
     use Perl6::Caller;

     my $sub         = caller->subroutine;
     my $line_number = caller->line;
     my $is_require  = caller(3)->is_require;

EXPORT
"caller"
     # standard usage
     print "In ",           caller->subroutine,
           " called from ", caller->file,
           " line ",        caller->line;

     # get a caller object
     my $caller = caller;
     my $caller = caller();   # same thing

     # get a caller object for a different stack from
     my $caller = caller(2);  # two stack frames up
     print $caller->package;  # prints the package name

     # enjoy the original flavor
     my @caller = caller;     # original caller behavior
     print $caller[0],        # prints the package name

DESCRIPTION
    This module is experimental. It's also alpha. Bug reports and patches
    welcome.

    By default, this module exports the "caller" function. This
    automatically returns a new "caller" object. An optional argument
    specifies how many stack frames back to skip, just like the
    "CORE::caller" function. This lets you do things like this:

     print "In ",           caller->subroutine,
           " called from ", caller->file,
           " line ",        caller->line;

    If you do not wish the "caller" function imported, specify an empty
    import list and instantiate a new "Perl6::Caller" object.

     use Perl6::Caller ();
     my $caller = Perl6::Caller->new;
     print $caller->line;

    Note: if the results from the module seem strange, please read
    perldoc -s caller carefully. It has stranger behavior than you might be
    aware.

METHODS
    The following methods are available on the "caller" object. They return
    the same values as documented in perldoc -f caller.

    There are no "hints" and "bitmask" methods because those are documented
    as for internal use only.

    *   "package"

    *   "filename"

    *   "line"

    *   "subroutine"

    *   "hasargs"

    *   "wantarray"

    *   "evaltext"

    *   "is_require"

    Note that each of these values will report correctly for when the caller
    object was created. For example, the following will probably print
    different line numbers:

     print caller->line;
     foo();
     sub foo { 
        print caller->line;
     }

    However, the following will print the *same* line numbers:

     my $caller = Perl6::Caller->new;   # everything is relative to here
     print $caller->line;
     foo($caller);
     sub foo { 
        my $caller = shift;
        print $caller->line;
     }

CAVEATS
    Most of the time, this package should *just work* and not interfere with
    anything else.

    *   $hints, $bitmask

        'hints' and 'bitmask' are not available. They are documented to
        be for internal use only and should not be relied upon. Further, the
        bitmask caused strange test failures, so I opted not to include
        them.

    *   "caller" package

        To make this work, we actually use the 'caller' package in addition
        to the "Perl6::Caller" package.

    *   Subclassing

        Don't.

    *   Perl 6

        I'm not entirely comfortable with the namespace. The Perl 6 caller
        actually does considerably more, but for me to have a hope of
        working that in, I need proper introspection and I don't have that.
        Thus, I've settled for simply having a caller object.

    *   *CORE::GLOBAL::caller

        I didn't implement this, though I was tempted. It turns out to be a
        bit tricky in spots and I'm very concerned about globally overriding
        behavior. I might change my mind in the future if there's enough
        demand.

    *   Overloading

        In string context, this returns the package name. This is to support
        the original "caller" behavior.

    *   List Context

        In list context, we simply default to the original behavior of
        "CORE::caller". However, this *always* assumes we've called caller
        with an argument. Calling "caller" and caller(0) are identical with
        this module. It's difficult to avoid since the stack frame changes.


Just curious, but...

phaylon on 2007-04-21T19:59:35

...for what exactly do you need the 'caller' namespace?

Re:Just curious, but...

Ovid on 2007-04-21T20:34:24

I don't. In the first (unreleased) version, I was having some serious issues with caller->line being called as a class method at times, but as caller()->line at other times (things got very strange which is part of why CORE::GLOBAL::caller has not been overridden). I can't quite work out how I got there, but I separated the namespace to make this work. Now I've fixed that and version 0.04 should be uploaded soon. Thanks for the prodding.