The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Test::Stream::Block - Tools to inspect coderefs

EXPERIMENTAL CODE WARNING

This is an experimental release! Test-Stream, and all its components are still in an experimental phase. This dist has been released to cpan in order to allow testers and early adopters the chance to write experimental new tools with it, or to add experimental support for it into old tools.

PLEASE DO NOT COMPLETELY CONVERT OLD TOOLS YET. This experimental release is very likely to see a lot of code churn. API's may break at any time. Test-Stream should NOT be depended on by any toolchain level tools until the experimental phase is over.

DESCRIPTION

This module is used to find line numbers, files, and other data about codeblocks. When used properly you can get both the start and end lines of codeblocks.

SYNOPSIS

    use Test::Stream::Block;

    sub new_block {
        my ($name, $code) = @_;
        my $block = Test::Stream::Block->new(
            name    => $name,
            coderef => $code,
            caller  => [caller],
        );
        return $block;
    }

    my $block = new_block foo => sub {
        ...
    };

    my $start_line = $block->start_line;
    my $end_line = $block->end_line;

HOW IT WORKS

Using the B module it is possible to get the line number of the first statement in a subroutine from the coderef. This makes it possible to get a rough approximation of the starting line number of a sub, usually it is off by 1, but will be correct for 1-line subs.

When you call a subroutine, then use caller() to get where the subroutine was called, you get the last line of the statement. If it is a 1 line statement you get the line number. If the statement uses multiple lines you get the last one.

    1: a_function "name" => sub { ... };

In the example above a_function() can get the calling line number 1 and the line of the first statement in the codeblock (also 1). With this information it could conclude that the codeblock is 1 line long, and is defined on line 1.

    01: a_function $name => sub {
    02:     my $self = shift;
    03:     ...
    04:     return 1;
    05: };

In this example a_function gets line number 5 from caller(). It can also get line 2 using B to inspect the coderef. With this information it can conclude that it is a multi-line codeblock, it knows that the first line is probably off by one and concludes it actually starts on line 1. At this point a_function() knows that the codeblock starts on line 1 and end on line 5.

When you pass in a named sub it will try its best to get the line numbers, it does this by actually reading in the file the sub was defined in and using some logic to approximate things. This is an 80% solution, it will get some things wrong.

CAVEATS

Some assumptions are made, for instance:

    01: a_function(
    02:     name => $name,
    03:     code => sub { ... },
    04: );

This will think the codeblock is defined from lines 2->4.

METHODS

$name = $block->name

This return the name provided to the constructor, or the name as deduced from the codeblock using B.

$sub = $block->coderef

This returns the coderef used to create the block object.

$caller = $block->caller

This returns an arrayref with the caller details provided at construction.

$package $block->package

This returns the deduced package.

$file = $block->file

This returns the deduced file.

$name = $block->subname

This returns the deduced sub name.

$block->run(@args)

This will run the coderef using any arguments provided.

$string = $block->detail

This returns a detail string similar to 'file foo.t line 5'. If start and end lines are known it will say '1 - 4'>, etc. It will adapt itself to provide whatever information it knows about the sub.

$line = $block->start_line

Get the starting line (or close to it).

$line = $block->end_line

Get the ending line (or close to it).

$arrayref = $block->deduced

Arrayref much like what you get from caller, but the details come from B instead.

SOURCE

The source code repository for Test::Stream can be found at http://github.com/Test-More/Test-Stream/.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright 2015 Chad Granum <exodist7@gmail.com>.

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

See http://www.perl.com/perl/misc/Artistic.html