File Coverage

blib/lib/Pad/Tie.pm
Criterion Covered Total %
statement 46 51 90.2
branch 4 6 66.6
condition 5 10 50.0
subroutine 10 13 76.9
pod 1 6 16.6
total 66 86 76.7


line stmt bran cond sub pod time code
1 2     2   62609 use strict;
  2         6  
  2         86  
2 2     2   11 use warnings;
  2         3  
  2         93  
3              
4             package Pad::Tie;
5              
6 2     2   1441 use Pad::Tie::LP;
  2         8  
  2         64  
7 2     2   3064 use Data::OptList;
  2         27365  
  2         18  
8             use Module::Pluggable (
9 2         22 require => 1,
10             except => qr/^Pad::Tie::Plugin::Base::/,
11 2     2   2158 );
  2         23849  
12 2     2   164 use Carp ();
  2         4  
  2         1125  
13              
14             our $VERSION = '0.006';
15             my %METHOD;
16              
17             sub new {
18 1     1 1 37 my $class = shift;
19 1         2 my ($invocant, $methods) = @_;
20 1         9 $methods = Data::OptList::mkopt($methods);
21 1         98 my $self = bless {
22             invocant => $invocant,
23             methods => $methods,
24             persist => Pad::Tie::LP->new,
25             pre_call => [],
26             } => $class;
27 1         38 $self->build_context;
28             #tie %{ $self->{context} }, 'Pad::Tie::Context', $self;
29 1         9 $self->{persist}->set_context(_ => $self->{context});
30 1         9 return $self;
31             }
32              
33             sub build_methods {
34 1   33 1 0 5 my $class = ref($_[0]) || $_[0];
35 1         7 for my $plugin ($class->plugins) {
36 8         22837 for my $provided ($plugin->provides) {
37             #warn "$plugin provides $provided\n";
38 8         93 $METHOD{$provided} = $plugin;
39             }
40             }
41             }
42              
43             sub build_context {
44 1     1 0 3 my $self = shift;
45 1   33     10 my $methods = shift || $self->{methods};
46 1   50     8 $self->{context} ||= {};
47 1 50       7 $self->build_methods unless %METHOD;
48 1         5 for (@$methods) {
49 8         15 my ($method_personality, $plugin_arg) = @$_;
50 8 50       22 Carp::confess "unhandled method personality: $method_personality"
51             unless $METHOD{$method_personality};
52 8         10 my $plugin = $METHOD{$method_personality};
53 8   100     44 my $rv = $plugin->$method_personality(
54             $self->{context},
55             $self->{invocant}, $plugin_arg,
56             ) || {};
57             # XXX I hate this but I can't think of a better way to do it offhand.
58             # if you aren't me, don't use this; talk to me about it instead. -- hdp,
59             # 2007-04-24
60 8 100       124 if ($rv->{pre_call}) {
61 3         4 push @{ $self->{pre_call} }, @{ $rv->{pre_call} };
  3         6  
  3         11  
62             }
63             }
64             }
65              
66             sub clone {
67 0     0 0 0 my ($self, $invocant) = @_;
68             # XXX validate $invocant?
69             # XXX does 'persist' need to be duplicated also?
70             # I don't think it has any permanent state that is interesting
71 0         0 return bless {
72             %$self,
73             invocant => $invocant,
74             } => ref($self),
75             }
76              
77             sub call {
78 9     9 0 1639 my ($self, $code, @args) = @_;
79 9         17 $_->($self, $code, \@args) for @{ $self->{pre_call} };
  9         78  
80 9         110 return $self->{persist}->call($code, @args);
81             }
82              
83             sub wrap {
84 0     0 0   my ($self, $code) = @_;
85 0     0     return sub { $self->call($code, @_) };
  0            
86             }
87              
88             1;
89              
90             __END__