File Coverage

blib/lib/self/implicit.pm
Criterion Covered Total %
statement 35 47 74.4
branch 7 16 43.7
condition n/a
subroutine 8 9 88.8
pod n/a
total 50 72 69.4


line stmt bran cond sub pod time code
1             package self::implicit;
2 1     1   652 use 5.006;
  1         4  
  1         42  
3 1     1   6 use strict;
  1         1  
  1         29  
4 1     1   5 use warnings;
  1         1  
  1         30  
5              
6 1     1   1270 use Devel::Declare ();
  1         7450  
  1         24  
7 1     1   977 use B::Hooks::Parser;
  1         965  
  1         38  
8 1     1   1033 use PadWalker qw(peek_my);
  1         930  
  1         662  
9              
10             our $VERSION = '0.34';
11              
12             my $NO_SELF;
13              
14             sub import {
15 1     1   10 my ($class) = @_;
16 1         3 my $caller = caller;
17              
18 1         33 B::Hooks::Parser::setup();
19              
20 1         5 my $linestr = B::Hooks::Parser::get_linestr();
21 1         4 my $offset = B::Hooks::Parser::get_linestr_offset();
22 1         6 substr($linestr, $offset, 0) = 'use PadWalker ();use B::OPCheck const => check => \&self::implicit::_check;';
23 1         38 B::Hooks::Parser::set_linestr($linestr);
24             }
25              
26             # This routine is almost the same as self::_check, the only difference is the injected $code.
27             sub _check {
28 23     23   12151 my $op = shift;
29 23         37 my $caller = caller;
30 23 50       65 return if $NO_SELF;
31 23 100       198 return unless ref($op->gv) eq 'B::PV';
32              
33 20         74 my $linestr = B::Hooks::Parser::get_linestr;
34 20         39 my $offset = B::Hooks::Parser::get_linestr_offset;
35              
36 20         23 my $code = q{if(ref($_[0]) ne __PACKAGE__){my $x = PadWalker::peek_my(1)->{'$self'};unshift @_,$$x if $x;};my($self,@args)=@_;};
37              
38 20 50       508 if (substr($linestr, $offset, 3) eq 'sub') {
    100          
39 0         0 my $line = substr($linestr, $offset);
40 0 0       0 if ($line =~ m/^sub\s.*{ /x ) {
41 0 0       0 if (index($line, "{$code") < 0) {
42 0         0 substr($linestr, $offset + index($line, '{') + 1, 0) = $code;
43 0         0 B::Hooks::Parser::set_linestr($linestr);
44             }
45             }
46             }
47              
48             # This elsif block handles:
49             # sub foo
50             # {
51             # ...
52             # }
53             elsif (index($linestr, 'sub') >= 0) {
54 4         11 $offset += Devel::Declare::toke_skipspace($offset);
55 4 50       103 if ($linestr =~ /(sub.*?\n\s*{)/) {
56 0           my $pos = index($linestr, $1);
57 0 0         if ($pos + length($1) - 1 == $offset) {
58 0           substr($linestr, $offset + 1, 0) = $code;
59 0           B::Hooks::Parser::set_linestr($linestr);
60             }
61             }
62             }
63              
64             }
65              
66             sub unimport {
67 0     0     my ($class) = @_;
68 0           my $caller = caller;
69 0           $NO_SELF = 1;
70             }
71              
72             1;
73              
74             __END__