File Coverage

blib/lib/Keyword/Pluggable.pm
Criterion Covered Total %
statement 47 52 90.3
branch 13 20 65.0
condition 11 15 73.3
subroutine 11 11 100.0
pod 2 2 100.0
total 84 100 84.0


line stmt bran cond sub pod time code
1             package Keyword::Pluggable;
2              
3 7     7   625473 use v5.14.0;
  7         26  
4 7     7   77 use warnings;
  7         16  
  7         691  
5             our %kw;
6              
7 7     7   88 use Carp qw(croak);
  7         14  
  7         563  
8              
9 7     7   44 use XSLoader;
  7         44  
  7         438  
10             BEGIN {
11 7     7   35 our $VERSION = '1.05';
12 7         7791 XSLoader::load __PACKAGE__, $VERSION;
13             }
14              
15             my %modes = (
16             'statement' => MODE_STATEMENT,
17             'expression' => MODE_EXPRESSION,
18             'dynamic' => MODE_DYNAMIC,
19             );
20              
21             sub define {
22 9     9 1 1087 my %p = @_;
23 9         39 my ($kw, $sub, $expression, $global, $package) = @p{qw(keyword code expression global package)};
24 9 50       74 $kw =~ /^\p{XIDS}\p{XIDC}*\z/ or croak "'$kw' doesn't look like an identifier";
25 9 50       24 defined($sub) or croak "'code' is not defined";
26 9   100     31 $expression //= 'statement';
27 9   66     49 my $sub_is_code = (ref($sub) and
28             (UNIVERSAL::isa($sub, 'CODE') or
29             $sub->isa('CODE')));
30 9 50 66     48 $sub_is_code or $expression ne 'dynamic' or croak("expression=dynamic requires a coderef");
31              
32 9 100   13   39 my $xsub = $sub_is_code ? $sub : sub { substr ${$_[0]}, 0, 0, $sub };
  13         390595  
  13         7201  
33              
34             my $entry = [ $xsub,
35 9 100 100     46 ($modes{$expression} //
36             ($expression? MODE_EXPRESSION: MODE_STATEMENT)) ];
37              
38 9 100       26 if ( defined $package) {
    100          
39 7     7   60 no strict 'refs';
  7         13  
  7         3006  
40 2         5 my $keywords = \%{$package . '::/keywords' };
  2         9  
41 2         46 $keywords->{$kw} = $entry;
42             } elsif ( $global ) {
43 2         35 define_global($kw, $entry);
44             } else {
45 5   100     9 my %keywords = %{$^H{+HINTK_KEYWORDS} // {}};
  5         45  
46 5         19 $keywords{$kw} = $entry;
47 5         173 $^H{+HINTK_KEYWORDS} = \%keywords;
48             }
49             }
50              
51             sub undefine {
52 1     1 1 229018 my %p = @_;
53 1         5 my ($kw, $global, $package) = @p{qw(keyword global package)};
54 1 50       12 $kw =~ /^\p{XIDS}\p{XIDC}*\z/ or croak "'$kw' doesn't look like an identifier";
55              
56 1 50       4 if ( defined $package ) {
    0          
57 7     7   61 no strict 'refs';
  7         15  
  7         1461  
58 1         2 my $keywords = \%{$package . '::/keywords' };
  1         6  
59 1         13 delete $keywords->{$kw};
60             } elsif ( $global ) {
61 0           undefine_global($kw);
62             } else {
63 0   0       my %keywords = %{$^H{+HINTK_KEYWORDS} // {}};
  0            
64 0           delete $keywords{$kw};
65 0           $^H{+HINTK_KEYWORDS} = \%keywords;
66             }
67             }
68              
69 7     7   900869 END { cleanup() }
70              
71             'ok'
72              
73             __END__