File Coverage

blib/lib/IO/All.pm
Criterion Covered Total %
statement 66 67 98.5
branch 9 14 64.2
condition 3 3 100.0
subroutine 15 16 93.7
pod 0 6 0.0
total 93 106 87.7


line stmt bran cond sub pod time code
1 3     3   75451 use strict; use warnings;
  3     3   7  
  3         119  
  3         18  
  3         6  
  3         119  
2             package IO::All;
3 3     3   1931 use IO::All::Base;
  3         10  
  3         17  
4              
5             has location => ();
6             has plugin_classes => (
7             default => sub { [qw(
8             IO::All::File
9             IO::All::Dir
10             )] }
11             );
12             option 'strict';
13             option 'overload';
14              
15             has methods => ( default => sub { +{} } );
16              
17             my $arg_key_pattern = qr/^-(\w+)$/;
18             sub import {
19 3     3   31 my $class = shift;
20 3         7 my $caller = caller;
21 3     3   17 no strict 'refs';
  3         6  
  3         896  
22 3         10 *{"${caller}::io"} = $class->make_constructor(@_);
  3         4693  
23             }
24              
25             sub make_constructor {
26 3     3 0 6 my $class = shift;
27 3         12 my $scope_args = $class->parse_args(@_);
28             return sub {
29 4 50   4   5191 $class->throw("'io' constructor takes zero or one arguments")
30             if @_ > 1;
31 4 100       52 my $location = @_ ? shift(@_) : undef;
32 4         86 $class->new([-location => $location], @$scope_args);
33 3         1470 };
34             }
35              
36             {
37 3     3   55 no warnings 'redefine';
  3         15  
  3         3154  
38             sub new {
39 4     4   18 my $class = shift;
40 4         19 my $self = bless {}, $class;
41 4         19 for (@_) {
42 7         26 my $property = shift(@$_);
43 7         45 $property =~ s/^-//;
44 7         47 $self->$property(@$_);
45             }
46 4         10 for my $plugin_class (@{$self->plugin_classes}) {
  4         20  
47 6 50       621 eval "require $plugin_class; 1"
48             or $self->throw("Can't require $plugin_class: $@");
49 6         33 $self->register_methods($plugin_class);
50 6         23 $self->register_overloads($plugin_class);
51 6 100       26 if ($plugin_class->can_upgrade($self)) {
52 3         20 $self->rebless($plugin_class);
53 3         11 last;
54             }
55             }
56 4         37 return $self;
57             }
58             }
59              
60             # Parse
61             # use IO::All -foo, -bar => 'x', 'y', -baz => 0;
62             # Into
63             # [ ['-foo'], ['-bar', 'x', 'y'], ['-baz, 0] ]
64             sub parse_args {
65 3     3 0 5 my $class = shift;
66 3         7 my $args = [];
67 3         12 while (@_) {
68 3         4 my $key = shift(@_);
69 3 50       17 die "Unknown argument '$key' for '$class' usage"
70             unless $key =~ $arg_key_pattern;
71 3         9 my $arg = [$1];
72 3   100     55 push @$arg, shift(@_)
73             while @_ and $_[0] !~ $arg_key_pattern;
74 3         11 push @$args, $arg;
75             }
76 3         9 return $args;
77             }
78              
79             sub with {
80 1     1 0 2 my $self = shift;
81 2 50       30 $self->plugin_classes([
82 1         3 map { /::/ ? $_ : __PACKAGE__ . "::$_" } @_
83             ]);
84             }
85              
86             sub register_methods {
87 6     6 0 14 my ($self, $plugin_class) = @_;
88 6         11 for my $method (@{$plugin_class->upgrade_methods}) {
  6         64  
89 12         37 $self->methods->{$method} = $plugin_class;
90             }
91             }
92              
93             sub register_overloads {
94 6     6 0 14 my ($self, $plugin_class) = @_;
95             }
96              
97             sub AUTOLOAD {
98 1     1   3 my $self = shift;
99 1         7 (my $method = $IO::All::AUTOLOAD) =~ s/.*:://;
100 1 50       4 my $plugin_class = $self->methods->{$method}
101             or $self->throw(
102             "Can't locate object method '$method' for '$self' object"
103             );
104 1         4 $self->rebless($plugin_class);
105 1         6 $self->$method(@_);
106             }
107              
108             sub rebless {
109 4     4 0 10 my ($self, $plugin_class) = @_;
110 4         12 delete $self->{plugin_classes};
111 4         13 bless $self, $plugin_class;
112 4         26 $self->upgrade;
113             }
114              
115 0     0     sub DESTROY {}
116              
117             1;