NAME
    Devel::Bug - Transparent inline debugging probe (pure Perl)

SYNOPSIS
        use Devel::Bug;                           # output to STDERR
        use Devel::Bug out => *STDOUT;            # redirect output
        use Devel::Bug ':pfl';                    # package + filename + lineno by default
        use Devel::Bug ':pfl', out => *STDOUT;    # label:flags with options
        use Devel::Bug bug => 'dbg';              # export under a different name

        # Scalar: value passes through; appears on STDERR (no label)
        my $result = bug = substr($str, $offset);
        # OUTPUT: (value)

        # Inline in any expression
        my $path = $dir . '/' . (bug('label') = substr($str, $offset));
        # OUTPUT: label=(images/logo.png)

        # List: parens around bug() are required to force list-context assignment
        my @items = (bug 'items') = get_items();
        # OUTPUT: items=(foo bar baz)

        # Flags in the label string
        my @items = (bug 'items:@')  = get_items();   # N: index prefixes
        my %hash  = (bug 'data:%')   = get_pairs();   # key => value format
        my %hash  = (bug 'data:@%')  = get_pairs();   # both
        my @items = (bug 'items:m')  = get_items();   # multiline

        # Per-call options
        my $x = (bug 'result', vc => 'green') = compute();

DESCRIPTION
    "Devel::Bug" exports bug(), named for the wiretap sense of the word:
    plant it inline inside any existing assignment to tap into values as
    they flow through your code. The value(s) assigned *through* bug() will
    reach the left-hand side unmodified; the only side effect is output to
    the configured filehandle. *For list assignments*, bug() must be
    *wrapped in parentheses* to force list context: "(bug ...) =
    list_expr()". Without them "bug" is called in scalar context and
    captures only a single value.

    Output format:

        label=(value)               # scalar
        label=(v1 v2 v3)            # list
        label=(a => 1 b => 2)       # keyval
        pkg file line: label=(...)  # with caller info enabled

    By default, ANSI colors are applied when the output handle is a
    terminal, and multiline layout is applied automatically when output
    would overflow the terminal width. Both behaviors are configurable; see
    "color", "delims", and "noterm".

IMPORT AND CALL OPTIONS
    Options apply in two contexts: as import-time defaults via "use" or
    import(), and as per-call overrides passed directly to bug().

        use Devel::Bug out => *STDOUT, lineno => 1;       # import-time defaults
        my $x = (bug 'result', vc => 'green') = ...;      # per-call override

    Options follow an optional label:flags string as key/value pairs (see
    "LABEL:FLAGS SYNTAX"). The "bug" option (export name) is only valid at
    import time.

  Output
    out (aliases: output, o)
        Filehandle to print to. Accepts anything "print" accepts as an
        indirect filehandle: typeglobs, lexical filehandles, and filehandle
        objects. Default: *STDERR.

            use Devel::Bug out => *STDOUT;    # typeglob
            use Devel::Bug out => $fh;        # lexical filehandle or object

  Caller information
    When enabled, the corresponding field is prepended to every line of
    output.

    package (aliases: pkg, p)
        Calling package name.

    filename (aliases: fn, f)
        Source filename.

    lineno (aliases: line, ln, l)
        Source line number.

  Display
    multiline (aliases: ml, m)
        Print each value on its own indented line.

    indices (aliases: indexes, index, i, @)
        Prefix each list element with "N:". Implies multiline.

    keyval (aliases: kv, k, %)
        Treat the list as alternating key/value pairs and format each as
        "key => value". Combine with "indices"/"@" to add "N:" prefixes; the
        index counts pairs, not individual elements. Implies multiline.

    delims (aliases: delimiters, d)
        Controls whether the value is wrapped in parentheses. Three states:

        "on" (also 1)
            Always wrap in parentheses.

        "off" (also "undef")
            Never wrap in parentheses.

        "auto" (also '', default)
            Wrap when output is not colored; omit when colored (color
            already delineates the value visually).

  Colors
    color
        Controls when ANSI colors are applied. Three states:

        "on" (also 1)
            Always apply colors, even to non-terminal output.

        "off" (also "undef")
            Never apply colors.

        "auto" (also '', default)
            Apply colors only when the output handle is a terminal.

    infocolor (alias: ic)
        Term::ANSIColor color specification for the caller-info prefix, e.g.
        'bold', 'cyan on_black'. Default: none.

    labelcolor (alias: lc)
        Color specification for the label. Default: 'bold'.

    valcolor (aliases: vc, valuecolor)
        Color specification for values. Default: 'red on_grey23'.

  Terminal detection
    noterm (aliases: noterminal, n)
        Disable terminal width detection. When set, neither "stty" nor
        Term::Size::Perl is consulted, making both entirely optional. With
        "noterm" enabled, terminal-width-based multiline layout is
        suppressed, and "color => 'auto'" behaves as if the output is not a
        terminal.

        A warning is issued if terminal detection is attempted, "stty size"
        fails, and Term::Size::Perl cannot be loaded. Set "noterm" to
        suppress both the detection and the warning.

  Pretty-printer
    pp  Fully-qualified name of the function used to format reference
        values, in the form 'Module::Name::function'. The function is called
        with the reference as its first argument and must return a string.
        The module is loaded automatically on first use. If the specified
        module cannot be loaded or the named sub does not exist, a warning
        is issued and the default is used instead.

        Default: 'Data::Dumper::Dumper'.

            use Devel::Bug pp => 'Data::Dump::pp';          # import-time default
            my $x = (bug 'data', pp => 'Data::Dump::pp') = get_data();  # per-call

  Alternative display value
    val (aliases: value, v, override)
        Display a different value in the output than the one being assigned.
        The actual assigned value still passes through unchanged.

        Use this when the assigned value is opaque or uninteresting, but a
        related value at the same point in the code is more informative.
        Particularly useful in ternary expressions, where the probe fires
        only when that branch is taken.

            # Without bug(): a do {} block is needed to log and still return a value
            my $installed =
                $sub =~ /^(.+)::/
                ?   do {
                        print "package=($1)\n";
                        *{ $caller . '::' . $name }= \&{ $sub }
                    }
                :   carp "Cannot determine package from '$sub'";

            # With bug(): val => $1 is displayed; the glob assignment passes through
            my $installed =
                $sub =~ /^(.+)::/
                ?   bug('package', val => $1)=
                        *{ $caller . '::' . $name }= \&{ $sub }
                :   carp "Cannot determine package from '$sub'";

  Export name
    bug Rename or suppress the exported function.

            use Devel::Bug bug => 'tap';   # exports as tap()
            use Devel::Bug bug => '';      # suppresses export  ('', 0, undef all work)

        The name must be a valid Perl identifier ("/^[a-z]\w*$/i" or
        "/^_\w+$/"). This option is only valid at import time; it may not be
        passed to bug().

LABEL:FLAGS SYNTAX
    A label:flags string may optionally appear as the *first* argument to
    bug() or "use" (import()).

    The string has the form "label:flags", where both parts are optional. A
    leading colon means an empty label; the characters after the colon each
    enable a boolean option by its single-char alias.

        use Devel::Bug ':pfl';            # empty label, flags p, f, l
        use Devel::Bug 'app:pf';          # label 'app', flags p, f
        use Devel::Bug 'app';             # label 'app', no flags

        my @r = (bug 'data:@%') = ...;   # label 'data', flags @ and %
        my @r = (bug ':m')      = ...;   # empty label, flag m

    Flag characters:

        @   i   indices      %   k   keyval       m   multiline
        p       package      f       filename     l   lineno
        d       delims       n       noterm

CHAINING
    Bug probes can be placed at different points in a pipeline to capture
    each intermediate value independently.

        my @data = (1, 2, 3, 4, 5, 6);
        my @doubled =
            (bug 'doubled')=      # parens make this a list assignment; bug() passes the whole list through
            map  { $_ * 2 }
            (bug 'evens')=        # parens force list context; without them bug() captures only one value
            grep { $_ % 2 == 0 } @data;

        # OUTPUT:
        # doubled=(4 8 12)
        # evens=(2 4 6)

    'evens' captures the elements that passed the grep; 'doubled' captures
    those elements after multiplication. Output fires left-to-right as Perl
    frees temporaries at end-of-statement, which is the reverse of data flow
    - hence 'doubled' prints before 'evens'.

DEPENDENCIES
    Term::ANSIColor, Data::Dumper.

    Terminal width detection first tries "stty size". Term::Size::Perl is
    loaded on demand only if "stty" is unavailable or returns no output, and
    is never consulted when "noterm" is set.

    Data::Dump and other pretty-printer modules are optional; see the "pp"
    option.

AUTHOR
    Kevin Shea

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

