File Coverage

blib/lib/Eval/Quosure.pm
Criterion Covered Total %
statement 49 49 100.0
branch n/a
condition 3 4 75.0
subroutine 16 16 100.0
pod 4 5 80.0
total 72 74 97.3


line stmt bran cond sub pod time code
1             package Eval::Quosure;
2              
3             # ABSTRACT: Evaluate within a caller environment
4              
5 1     1   216655 use 5.010;
  1         8  
6 1     1   5 use strict;
  1         2  
  1         19  
7 1     1   4 use warnings;
  1         1  
  1         42  
8              
9             our $VERSION = '0.001000'; # VERSION
10              
11 1     1   5 use List::Util 1.28 qw(pairmap);
  1         16  
  1         75  
12 1     1   460 use PadWalker 2.3 qw(peek_my peek_our);
  1         695  
  1         62  
13 1     1   453 use Safe::Isa 1.000009;
  1         554  
  1         127  
14 1     1   501 use Sub::Quote 2.005 qw(quote_sub);
  1         5064  
  1         58  
15 1     1   633 use Type::Params 1.004004;
  1         94476  
  1         8  
16 1     1   361 use Types::Standard qw(Str Int HashRef Optional);
  1         2  
  1         5  
17              
18             sub new {
19 2     2 0 978 state $check = Type::Params::compile( Str, Optional [Int] );
20              
21 2         2196 my $class = shift;
22 2         70 my ( $expr, $level ) = $check->(@_);
23 2   100     43 $level //= 0;
24              
25             my $captures = {
26 5     5   14 pairmap { $a => $b }
27 2         10 ( %{ peek_our( $level + 1 ) }, %{ peek_my( $level + 1 ) } )
  2         20  
  2         18  
28             };
29              
30 2         35 my $self = bless {
31             expr => $expr,
32             captures => $captures,
33             caller => [ caller($level) ],
34             }, $class;
35 2         8 return $self;
36             }
37              
38              
39 4     4 1 30 sub expr { $_[0]->{expr} }
40 4     4 1 36 sub captures { $_[0]->{captures} }
41 4     4 1 9 sub caller { $_[0]->{caller} }
42              
43              
44             sub eval {
45 4     4 1 7778 state $check = Type::Params::compile( Optional [HashRef] );
46              
47 4         1463 my $self = shift;
48 4         64 my ($additional_captures) = $check->(@_);
49 4   50     49 $additional_captures //= {};
50              
51             my $captures =
52 4     6   7 { %{ $self->captures }, pairmap { $a => \$b } %$additional_captures };
  4         10  
  6         21  
53 4         18 my $caller = $self->caller;
54              
55 4         10 my $coderef = quote_sub(
56             undef,
57             $self->expr,
58             $captures,
59             {
60             no_install => 1, # do not install the function
61             package => $caller->[0],
62             file => $caller->[1],
63             line => $caller->[2],
64              
65             # Without below it would get error with Function::Parameters
66             # https://rt.cpan.org/Public/Bug/Display.html?id=122698
67             hintshash => undef,
68             }
69             );
70 4         330 return $coderef->();
71             }
72              
73             1;
74              
75             __END__