File Coverage

blib/lib/Data/Object/Prototype.pm
Criterion Covered Total %
statement 79 79 100.0
branch 6 10 60.0
condition 3 8 37.5
subroutine 20 20 100.0
pod 0 3 0.0
total 108 120 90.0


line stmt bran cond sub pod time code
1             # ABSTRACT: Data::Object Prototype-based Programming
2             package Data::Object::Prototype;
3              
4 1     1   18623 use 5.10.0;
  1         3  
  1         57  
5              
6 1     1   6 use strict;
  1         2  
  1         41  
7 1     1   6 use warnings;
  1         6  
  1         32  
8              
9 1     1   4 use Carp qw(croak);
  1         1  
  1         60  
10 1     1   409 use Clone qw(clone);
  1         2494  
  1         89  
11 1     1   667 use Data::Object qw(deduce_type);
  1         1922  
  1         69  
12 1     1   5 use Scalar::Util qw(blessed);
  1         1  
  1         58  
13              
14             our $VERSION = '0.02'; # VERSION
15              
16             sub import {
17 2     2   151 my $class = shift;
18 2         3 my $target = caller;
19              
20 1     1   19 no strict 'refs';
  1         2  
  1         335  
21              
22 2         17 *{"${target}::extend"} = $class->can('build_clone');
  2         7  
23 2         7 *{"${target}::object"} = $class->can('build_object');
  2         7  
24              
25 2         1505 return;
26             }
27              
28             my $serial = 0;
29             sub build_class (@) {
30 4     4 0 6 my $type = shift;
31 4         5 my $base = shift;
32              
33 4         29 my $mappings = {
34             'ARRAY' => 'Data::Object::Array',
35             'HASH' => 'Data::Object::Hash',
36             'CODE' => 'Data::Object::Code',
37             'FLOAT' => 'Data::Object::Float',
38             'NUMBER' => 'Data::Object::Number',
39             'INTEGER' => 'Data::Object::Integer',
40             'STRING' => 'Data::Object::String',
41             'SCALAR' => 'Data::Object::Scalar',
42             'REGEXP' => 'Data::Object::Regexp',
43             'UNDEF' => 'Data::Object::Undef',
44             'UNIVERSAL' => 'Data::Object::Universal',
45             };
46              
47 4         10 my $class = join '::', __PACKAGE__, 'Instance';
48              
49 4   50     11 $type = $mappings->{$type} // 'Data::Object::Universal';
50 4 100       7 $base = $class unless $base;
51              
52 4         6 my $format = '%s::__ANON__::%04d';
53 4         12 my $package = sprintf $format, $class, ++$serial;
54 4         13 my @supers = ("use base '$type'", "use base '$base'");
55              
56 1     1   6 eval join '; ', ("package $package", @supers);
  1     1   2  
  1     1   95  
  1     1   4  
  1     1   2  
  1     1   556  
  1     1   4  
  1     1   1  
  1         88  
  1         4  
  1         1  
  1         342  
  1         4  
  1         1  
  1         63  
  1         4  
  1         2  
  1         247  
  1         4  
  1         2  
  1         65  
  1         4  
  1         2  
  1         281  
  4         267  
57              
58 4 50       13 croak $@ if $@;
59              
60 4         51 return $package;
61             }
62              
63             sub build_clone (@) {
64 3     3 0 23 my $class = shift;
65 3         4 my $args = shift;
66              
67 3 50 33     21 $args = clone $class->data if not defined $args && ref $class;
68              
69 3         8 my $type = deduce_type $class;
70 3   33     65 my $clone = build_class $type, ref($class) || $class;
71              
72 3 50       12 $args = blessed $args ? $args->data : $args;
73              
74 3         18 return $clone->new($args);
75             }
76              
77             sub build_object (@) {
78 1     1 0 414 my $args = shift;
79              
80 1         8 my $type = deduce_type $args;
81 1         63786 my $class = build_class $type;
82              
83 1 50       8 $args = blessed $args ? $args->data : $args;
84              
85 1         11323 return $class->new($args);
86             }
87              
88             1;
89              
90             __END__