File Coverage

blib/lib/Context/Handle.pm
Criterion Covered Total %
statement 93 94 98.9
branch 9 12 75.0
condition 2 2 100.0
subroutine 33 33 100.0
pod 15 18 83.3
total 152 159 95.6


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Context::Handle;
4 2     2   44139 use base qw/Exporter/;
  2         4  
  2         218  
5              
6 2     2   10 use strict;
  2         2  
  2         62  
7 2     2   13 use warnings;
  2         8  
  2         52  
8              
9 2     2   1677 use Want ();
  2         3998  
  2         49  
10 2     2   12 use Carp qw/croak/;
  2         3  
  2         85  
11              
12 2     2   982 use Context::Handle::RV::Scalar;
  2         5  
  2         50  
13 2     2   1019 use Context::Handle::RV::Void;
  2         4  
  2         47  
14 2     2   1249 use Context::Handle::RV::List;
  2         4  
  2         44  
15 2     2   952 use Context::Handle::RV::Bool;
  2         5  
  2         42  
16 2     2   1000 use Context::Handle::RV::RefHash;
  2         3  
  2         42  
17 2     2   982 use Context::Handle::RV::RefArray;
  2         4  
  2         41  
18 2     2   944 use Context::Handle::RV::RefScalar;
  2         4  
  2         40  
19 2     2   1024 use Context::Handle::RV::RefCode;
  2         5  
  2         41  
20 2     2   983 use Context::Handle::RV::RefObject;
  2         5  
  2         62  
21              
22             BEGIN {
23 2     2   1383 our @EXPORT_OK = qw/context_sensitive/;
24             }
25              
26             our $VERSION = "0.01";
27              
28             sub context_sensitive (&) {
29 5     5 1 8973 my $code = shift;
30 5         22 __PACKAGE__->new( $code, 1 );
31             }
32              
33             sub new {
34 7     7 1 526 my $pkg = shift;
35 7         9 my $code = shift;
36 7 100       21 my $caller_level = @_ ? 1 + shift : 1;
37              
38 7         29 my $self = bless {
39             uplevel => $caller_level,
40             want_reftype => Want::wantref( $caller_level + 1 ),
41             want_count => Want::want_count($caller_level),
42             want_wantarray => Want::wantarray_up($caller_level),
43             want_bool => Want::want_uplevel($caller_level, "BOOL"),
44             want_assign => [ Want::wantassign( $caller_level + 1 ) ],
45             want_lvalue => Want::want_lvalue( $caller_level ),
46             }, $pkg;
47              
48 7         597 $self->eval( $code) ;
49              
50 6         35 $self;
51             }
52              
53             sub bool {
54 4     4 1 9 my $self = shift;
55 4 50       16 $self->{want_bool} && defined $self->{want_wantarray};
56             }
57              
58             sub void {
59 2     2 1 3 my $self = shift;
60 2         12 not defined $self->{want_wantarray};
61             }
62              
63             sub scalar {
64 7     7 1 8 my $self = shift;
65 7 50       59 defined $self->{want_wantarray} && $self->{want_wantarray} == 0;
66             }
67              
68             sub list {
69 2     2 1 4 my $self = shift;
70 2         10 $self->{want_wantarray};
71             }
72              
73             sub refarray {
74 5     5 1 7 my $self = shift;
75 5         20 $self->{want_reftype} eq 'ARRAY';
76             }
77              
78             sub refhash {
79 4     4 1 8 my $self = shift;
80 4         13 $self->{want_reftype} eq 'HASH';
81             }
82              
83             sub refscalar {
84 5     5 1 8 my $self = shift;
85 5         16 $self->{want_reftype} eq 'SCALAR';
86             }
87              
88             sub refobject {
89 4     4 1 5 my $self = shift;
90 4         13 $self->{want_reftype} eq 'OBJECT';
91             }
92              
93             sub refcode {
94 4     4 1 7 my $self = shift;
95 4         14 $self->{want_reftype} eq 'CODE';
96             }
97              
98             sub refglob {
99 4     4 1 6 my $self = shift;
100 4         15 $self->{want_reftype} eq 'GLOB';
101             }
102              
103              
104             sub rv_subclass {
105 7     7 0 8 my $self = shift;
106              
107 7 100       19 if ( $self->scalar ) {
108 5         12 for (qw/RefArray RefScalar RefHash RefObject RefCode RefGlob/) {
109 26         37 my $meth = lc;
110 26 100       62 return $_ if $self->$meth;
111             }
112              
113 4 50       11 return "Bool" if $self->bool;
114              
115 4         19 return "Scalar";
116             } else {
117 2   100     8 $self->$_ and return ucfirst for qw/void list/;
118             }
119              
120 0         0 die "dunno how to do this context.";
121             }
122              
123             sub mk_rv_container {
124 7     7 0 8 my $self = shift;
125 7         9 my $code = shift;
126              
127 7         17 my $subclass = $self->rv_subclass;
128 7         51 "Context::Handle::RV::$subclass"->new($code);
129             }
130              
131             sub eval {
132 7     7 0 11 my $self = shift;
133 7         8 my $code = shift;
134              
135 7         18 $self->{rv_container} = $self->mk_rv_container($code);
136             }
137              
138             sub rv_container {
139 8     8 1 22 my $self = shift;
140 8         37 $self->{rv_container};
141             }
142              
143             sub value {
144 6     6 1 15 my $self = shift;
145 6         21 $self->rv_container->value;
146             }
147              
148             sub return {
149 6     6 1 18 my $self = shift;
150 6         17 Want::double_return();
151 6         19 $self->value;
152             }
153              
154              
155             __PACKAGE__;
156              
157             __END__