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
AUTHORS
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