NAME
    Stacktrace::Configurable - a configurable Perl stack trace

SYNOPSIS
     use Stacktrace::Configurable;

     Stacktrace::Configurable->new(format=>$fmt)->get_trace->as_string;

DESCRIPTION
    The idea for "Stacktrace::Configurable" came when I needed a easily
    readable stack trace in Log::Log4perl output. That distribution's
    pattern layout can give you a stack trace but it's not very readable.
    There are other modules out there that provide a caller stack, like
    Devel::StackTrace and Carp. Choose what suits you best.

    A stack trace is basically a list of stack frames starting with the
    place where the get_trace method is called down to the main program. The
    first element in that list is also called the topmost frame.

    Each frame of the list collected by get_trace is a
    Stacktrace::Configurable::Frame object which provides simple accessors
    for the information returned by "caller". Additionally, a frame has a
    "nr" in Stacktrace::Configurable::Frame attribute which contains its
    position in the list starting from 1 (topmost).

  Constructor
    The constructor "Stacktrace::Configurable->new" is called with a list of
    key/value pairs as parameters. After constructing an empty object it
    uses each of those keys as method name and calls it passing the value as
    parameter.

    Example:

     $trace=Stacktrace::Configurable->new(format=>$fmt);

  Attributes
    Attributes are simple accessor methods that provide access to scalar
    variables stored in the object. If called with a parameter the new value
    is stored. The return value is always the new or current value.

    These attributes are implemented:

    format
        the format specification, see below

    frames
        the stack trace. It is an arrayref of
        Stacktrace::Configurable::Frame objects usually initialized by the
        get_trace method.

  Public Methods
    $obj->get_trace
        collects the stack trace with the caller of "get_trace" as the
        topmost frame and stores it as "$obj->frames".

        Returns the object itself to allow for chained calls like

         $obj->get_trace->as_string;

    $obj->as_string
        formats the stack trace according to the current format and returns
        the resulting string.

  Methods interesting for subclassing
    $obj->skip_package_re
        returns the empty list. If overwritten by subclasses, it should
        return a regular expression matching package names which is used to
        skip stack frames from the top of the stack. "get_trace" starts to
        collect stack frames from the top of the stack. If "skip_package_re"
        returns a regexp, it drops those frames as long as their "package"
        matches the regexp. Once a non-matching package is discovered all
        remaining frames are included in the trace no matter what "package".

        This allows you to skip frames internal to your subclass from the
        top of the stack if you are not sure of the nesting level at which
        "get_trace" is called.

    $obj->skip_package_number
        Similar to "skip_package_re", only it specifies the actual nesting
        level. For the base class ("Stacktrace::Configurable") 1 is
        returned.

    $obj->default_format
        this method returns a constant that is used by the constructor to
        initialize the "format" attribute if omitted.

        The current default format is:

         'env=STACKTRACE_CONFIG,'.
         '%[nr=1,s=    ==== START STACK TRACE ===]b%[nr=1,n]b'.
         '%4b[%*n] at %f line %l%[n]b'.
         '%12b%[skip_package]s %[env=STACKTRACE_CONFIG_A]a'.
         '%[nr!STACKTRACE_CONFIG_MAX,c=%n    ... %C frames cut off]b'.
         '%[nr=$,n]b%[nr=$,s=    === END STACK TRACE ===]b%[nr=$,n]b'

    $obj->fmt_b
    $obj->fmt_n
    $obj->fmt_s
    $obj->fmt_a
    $obj->fmt_f
    $obj->fmt_l
    $obj->fmt_c
    $obj->fmt_p
        these methods format a certain portion of a stack frame. They are
        called as methods. So, the first parameter is the object itself. The
        following parameters are:

        $frame
            the frame to format

        $width
            the width part of the format specification

        $param
            the param part of the format specification

        Return value: the formatted string

  Private Methods
    $obj->_use_dumper

  Format
    The format used by Stacktrace::Configurable is inspired by "printf" and
    Log::Log4perl::Layout::PatternLayout.

    The first format component is an optional string starting with "env="
    and ending in a comma, like

     env=STACKTRACE_CONFIG,

    If this component is found "as_string" consults the specified
    environment variable for instructions. If the variable is "off", "no" or
    0, no stack trace at all is created and "as_string" returns the empty
    string.

    If after stripping of that first component, the format becomes the empty
    string the value of the environment variable or, if also empty, the
    default format is used as format specification.

    The rest of the format is a string with embedded format specifications
    or *fspec*. An fspec starts with a percent sign, "%". Then follows an
    optional width component, an optional parameter component and the
    mandatory format letter.

    The width component is just an integer number optionally prepended with
    a minus sign or an asterisk ("*"). Not every fspec uses the width
    component or does something useful for "*".

    The parameter component is surrounded by brackets ("[]").

    The parsing of an fspec is kept simple. So, it does not support nested
    brackets or similar.

    The following format letters are implemented:

    b   Originally the name "b" was chosen because "s" was already in use.
        It stands for *blank* or empty space. Though, it can generate
        arbitrary output and be based on conditions.

        The simplest form %b just outputs one space. Add a width component,
        %20b and you get 20 spaces.

        The parameter component is a set of 2 optional items separated by
        comma. The first item specifies a condition. The second modifies the
        string used in place of the space.

        Let's first look at examples where the condition part is omitted.
        The "n" parameter tells to use a newline instead of a space. So,
        "%20[n]b" inserts 20 newline characters. The parameter "t" does the
        same only that a tabulator character is used. "%20[t]b" results in
        20 tabs. The 3rd option is the "s=" parameter. It allows you to
        specify arbitrary strings. "%4[s=ab]b" results in

         abababab

        Now, let's look at conditional output. The "nr=" parameter matches a
        specific stack frame given by its number. It is most useful at the
        start and the end of the stack trace.

        Examples:

         %[nr=1,s=stack trace start]b

        if given at the beginning of the format, this specification prints
        the string "stack trace start" but only for the topmost frame.

         %[nr=$,s=stack trace end]b

        "nr=$" matches only for the last stack frame. So, the fspec above
        prints "stack trace end" at the end of the trace.

        The "nr!" condition also matches a specific frame given by its
        number. But in addition to generate output it cuts off the trace
        after the current frame. It is used if you want to print only the
        topmost N frames. It is often used with the empty string as what to
        print, like

         %[nr!10,s=]b

        This prints nothing but cuts off the stack trace after the 10th
        frame.

        If the part after the exclamation mark is not a number but matches
        "\w+", it is taken as the name of an environment variable. If set
        and if it is a number, that number is taken instead of the literal
        number above.

        In combination with this condition there is another parameter to
        specify the string, "c=" or the cutoff message. It is printed only
        if there has been cut off at least one frame. Also, the cutoff
        message can contain %n and %C (capital C). The former is replaced by
        a newline, the latter by the number of frames cut off.

        This allows for the following pattern:

         %[nr!MAX,c=%ncutting off remaining %C frames]n

        Now, let's assume "$ENV{MAX}=4" but the actual stack is 20 frames
        deep. The specification tells to insert an additional newline for
        the 4th frame followed by the string "cutting off remaining 16
        frames".

        The last condition is "nr%N" and "nr%N=M". It can be used to insert
        a special delimiter after every N stack frames.

         %[nr%10=1,n]b%80[nr%10=1,s==]b

        prints a delimiter consisting of a newline and 80 equal signs after
        every 10th frame.

        The condition is true if "frame_number % M == N" where N defaults to
        0.

    n   inserts the frame number. This format ignores the parameter
        component. Width can be given as positive or negative number an is
        interpreted just like in "sprintf". If width is "*" or "-*", the
        actual width is taken to fit the largest frame number.

        Examples:

         %n
         %4n
         %-4n
         %*n
         %-*n

    s   inserts the subroutine. The width component is ignored and only one
        parameter is known, "skip_package". If specified, the package where
        the function belongs to is omitted.

        Examples:

         %s                   # might print "Pack::Age::fun"
         %[skip_package]s     # prints only "fun"

    a   inserts the subroutine arguments. The width component is ignored.
        The parameter component is a comma separated list of

        dump
            all arguments are dumped using Data::Dumper. The dumper object
            is configured in a way to print the whole thing in one line.

            This may cause very verbose stack traces.

        dump=Pack::Age
            all arguments for which "ref" returns "Pack::Age" are dumped
            using Data::Dumper.

            You can, of course, also dump simple ARRAYs, HASHes etc.

        dump=/regexp/
            all arguments for which "ref" matches the regexp are dumped
            using Data::Dumper.

            If multiple such parameters are given, an argument that matches
            at least one regexp is dumped.

        deparse
            if "dump" or "dump=CODE" is also specified, the dumper object is
            configured to deparse the subroutine that is passed in the
            argument.

        multiline
        multiline=N
        multiline=N.M
            normally, all arguments are printed in one line separated by
            comma and space. With this parameter every argument is printed
            on a separate line.

            A format containing "%s %[multiline]a" would for instance
            generate this output:

             main::function (
                     "param1",
                     2,
                     "p3"
                 )

            The surrounding parentheses are part of the %a output.

            "N" and "M" are indentation specifications. "N" tells how many
            positions the closing parenthesis is indented. "M" tells how
            many positions further each parameter is indented. The default
            value for both is 4.

        env=ENVVAR
            This parameter reads the environment variable "ENVVAR" and
            appends it to the parameter list.

        Examples:

         %[dump,deparse,multiline]a    # very verbose

    f   inserts the file name. This fspec recognizes the following
        parameters:

        skip_prefix=PREFIX
            if the file name of the stack frame begins with "PREFIX", it is
            cut off.

            For instance, if your personal Perl modules are installed in
            /usr/local/perl, then you might specify

             %[skip_prefix=/usr/local/perl/]f

        basename
            cuts off the directory part of the file name.

            If a width component is specified and the file name is longer
            than the absolute value of the given width, then if the width is
            positive, the file name is cut at the end to meet the given
            width. If the width is negative, the file name is cut at the
            start to meet the width. Then an ellipsis (3 dots) is appended
            or prepended.

    l   inserts the line number. The width component is interpreted like in
        "sprintf".

    c   prints the context of the subroutine call as "void", "scalar" or
        "list".

    p   prints the package name of the stack frame.

        The %p fspec recognizes the "skip_prefix" parameter just like %f.

        The width component is also interpreted the same way as for %f.

    Examples:

     env=T,%f(%l)   # one line of "filename.pm(23)" for each frame
                    # unless $ENV{T} is "off", "no" or "0"

     env=T,         # use the format given in $ENV{T}
                    # unless $ENV{T} is "off", "no" or "0"

  Subclassing
    TODO

AUTHOR
    Torsten Förtsch <torsten.foertsch@gmx.net>

COPYRIGHT
    Copyright 2014- Torsten Förtsch

LICENSE
    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

SEE ALSO
    Carp, Devel::StackTrace,
    Log::Log4perl::Layout::PatternLayout::Stacktrace

