Test::Stream::Util - Tools used by Test::Stream and friends.


This distribution is deprecated in favor of Test2, Test2::Suite, and Test2::Workflow.

See Test::Stream::Manual::ToTest2 for a conversion guide.


Collection of tools used by Test::Stream and friends.


All exports are optional, you must specify subs to import. If you want to import everything use '-all'.

    use Test::Stream::Util '-all';
($success, $error) = try { ... }

Eval the codeblock, return success or failure, and the error message. This code protects $@ and $!, they will be restored by the end of the run. This code also temporarily blocks $SIG{DIE} handlers.

protect { ... }

Similar to try, except that it does not catch exceptions. The idea here is to protect $@ and $! from changes. $@ and $! will be restored to whatever they were before the run so long as it is successful. If the run fails $! will still be restored, but $@ will contain the exception being thrown.


Returns true if threads are enabled, false if they are not.


This will return the id of the current thread when threads are enabled, otherwise it returns 0.

my $file = pkg_to_file($package)

Convert a package name to a filename.

$stash = get_stash($package)

Returns the stash reference for the given package. The stash reference can be treated like a hashref, you can get keys and values from it.

$slot = sig_to_slot($sigil)

Given a sigil such as $, @, %, &, *, this will return the GLOB slot for that sigil such as SCALAR, ARRAY, HASH, CODE, GLOB.

$sigil = slot_to_sig($slot)

Given a a glob slot such as SCALAR, ARRAY, HASH, CODE, GLOB, this will return the typical sigil for that slot such as $, @, %, &, *.

($name, $type) = parse_symbol($symbol)

When given a symbol name such as $foo or @bar this will return the symbol name, and the type name. If no sigil is present in the variable name it will assume it is a subroutine and return the CODE type. $symbol should be a string containing the name of the symbol with optional sigil.

my $cols = term_size()

Attempts to find the width in columns (characters) of the current terminal. Returns 80 as a safe bet if it cannot find it another way. This is most accurate if Term::ReadKey is installed.

$type = rtype($ref)

A normalization between Scalar::Util::reftype() and ref().

Always returns a string.

Returns 'REGEXP' for regex types

Returns '' for non-refs

Otherwise returns what Scalar::Util::reftype() returns.

$addr_str = render_ref($ref)

Always returns a string. For unblessed references this returns something like "SCALAR(0x...)". For blessed references it returns "My::Thing=SCALAR(0x...)". The only difference between this and $add_str = "$thing" is that it ignores any overloading to ensure it is always the ref address.

$bool = CAN_SET_SUB_NAME()

A constant, it returns true if either Sub::Name or Sub::Util are installed and have the code necessary to set a sub name.

set_sub_name($name, $coderef)

When Sub::Name or Sub::Util are installed, this will be an alias to the sub name setting function from one or the other. If neither are installed then this will be a sub that throws an exception.

If setting the sub name is something nice, but not strictly necessary, you can use this conditionally with CAN_SET_SUB_NAME().

    use Test::Stream::Util qw/CAN_SET_SUB_NAME set_sub_name/;
    set_sub_name('foo', \&sub) if CAN_SET_SUB_NAME();
my $hr = sub_info(\&code)

This returns a hashref with information about the sub:

        ref        => \&code,
        cobj       => $cobj,
        name       => "Some::Mod::code",
        file       => "Some/",
        package    => "Some::Mod",

        # Note: These have been adjusted based on guesswork.
        start_line => 22,
        end_line   => 42,
        lines      => [22, 42],

        # Not a bug, these lines are different!
        all_lines  => [23, 25, ..., 39, 41],
$info->{ref} => \&code

This is the original sub passed to sub_info().

$info->{cobj} => $cobj

This is the c-object representation of the coderef.

$info->{name} => "Some::Mod::code"

This is the name of the coderef, for anonymous coderefs this may end with '__ANON__'. Also note that the package 'main' is special, and 'main::' may be omitted.

$info->{file} => "Some/"

The file in which the sub was defined.

$info->{package} => "Some::Mod"

The package in which the sub was defined.

$info->{start_line} => 22
$info->{end_line} => 42
$info->{lines} => [22, 42]

These 3 fields are the adjusted start line, end line, and array with both. It is important to note that these lines have been adjusted and may not be accurate.

The lines are obtained by walking the ops, as such the first line is the line of the first statement, and the last line is the line of the last statement. This means that in multi-line subs the lines are usually off by 1. The lines in these keys will be adjusted for you if it detects a multi-line sub.

$info->{all_lines} => [23, 25, ..., 39, 41]

This is an array with the lines of every statement in the sub. unlike the other line fields, these have not been adjusted for you.

update_mask($file, $line, $sub, {...})

This sets masking behavior in accordance with Trace::Mask. This will have no effect on anything that does not honor Trace::Mask.


The source code repository for Test::Stream can be found at


Chad Granum <>


Chad Granum <>
Kent Fredric <>


Copyright 2015 Chad Granum <>.

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