Skip Menu |

This queue is for tickets about the PPIx-LineToSub CPAN distribution.

Report information
The Basics
Id: 107261
Status: new
Priority: 0/
Queue: PPIx-LineToSub

People
Owner: Nobody in particular
Requestors: KENTNL [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.33
Fixed in: (no value)



Subject: Lines after closing "}" considered "Inside" the sub.

I was evaluating this module to see if I could use it for something, and in my basic assumptions test I discovered that in the given code:

1: package Foo;
2:
3: sub bar {
4: 
5:}
6:
7:my $code = sub {
8:
9:};
10:

lines 6 to 10 are considered "inside bar"

A quick analysis concludes that the code at present relies on new sub declarations to invalidate old ones, so you abuse a subsequent "sub" statement to mean "end of previous sub", when you should really be looking at PPI::Statement::Sub->block->finish->location
 

Additionally, the present code will also assume that forward declared subs like:

    sub foo();

Are full blocks, and lines appearing after them are *also* logically inside 'foo'

Attached is my test case which I have todoised the failing examples.

 

Subject: line_to_sub.t
#!/usr/bin/env perl # ABSTRACT: Ensure PPIx::LineToSub does what I think it does use strict; use warnings; use Test::More; use PPI::Util qw( _Document ); use PPIx::LineToSub; my $code = <<"EOF"; sub un_packaged { } package Example; sub sub_a { } package OtherExample; sub sub_b { } my \$anonsub = sub { }; sub forward(); my \$code = q//; EOF my $dom = _Document( \$code ); $dom->index_line_to_sub; is_linesub( 1, 'main', 'main' ); is_linesub( 2, 'main', 'un_packaged' ); is_linesub( 3, 'main', 'un_packaged' ); is_linesub( 4, 'main', 'un_packaged' ); { local $TODO = "broken"; is_linesub( 5, 'main', 'main' ); } is_linesub( 6, 'Example', 'main' ); is_linesub( 7, 'Example', 'main' ); is_linesub( 8, 'Example', 'sub_a' ); is_linesub( 9, 'Example', 'sub_a' ); is_linesub( 10, 'Example', 'sub_a' ); { local $TODO = "broken"; is_linesub( 11, 'Example', 'main' ); } is_linesub( 12, 'OtherExample', 'main' ); is_linesub( 13, 'OtherExample', 'main' ); is_linesub( 14, 'OtherExample', 'sub_b' ); is_linesub( 15, 'OtherExample', 'sub_b' ); is_linesub( 16, 'OtherExample', 'sub_b' ); { local $TODO = "broken"; is_linesub( 17, 'OtherExample', 'main' ); is_linesub( 18, 'OtherExample', 'main' ); is_linesub( 19, 'OtherExample', 'main' ); is_linesub( 20, 'OtherExample', 'main' ); is_linesub( 21, 'OtherExample', 'main' ); } is_linesub( 22, 'OtherExample', 'forward' ); { local $TODO = "broken"; is_linesub( 23, 'OtherExample', 'main' ); } done_testing; sub is_linesub { my ( $line, $package, $sub ) = @_; my ( $got_package, $got_sub ) = $dom->line_to_sub($line); note "line_to_sub($line)"; if ( defined $package ) { cmp_ok( $got_package, q[eq], $package, "line $line is package $package" ); } else { ok( !defined $got_package, "line $line has undefined package" ) or diag explain $got_package; } if ( defined $sub ) { cmp_ok( $got_sub, q[eq], $sub, "line $line is sub $sub" ); } else { ok( !defined $got_sub, "line $line is undefined sub" ) or diag explain $got_sub; } }