File Coverage

blib/lib/Data/Object/Prototype.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 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   25545 use 5.10.0;
  1         4  
  1         61  
5              
6 1     1   10 use strict;
  1         2  
  1         45  
7 1     1   5 use warnings;
  1         11  
  1         43  
8              
9 1     1   7 use Carp qw(croak);
  1         2  
  1         89  
10 1     1   1280 use Clone qw(clone);
  0            
  0            
11             use Data::Object qw(deduce_type);
12             use Scalar::Util qw(blessed);
13              
14             our $VERSION = '0.01'; # VERSION
15              
16             sub import {
17             my $class = shift;
18             my $target = caller;
19              
20             no strict 'refs';
21              
22             *{"${target}::extend"} = $class->can('build_clone');
23             *{"${target}::object"} = $class->can('build_object');
24              
25             return;
26             }
27              
28             my $serial = 0;
29             sub build_class (@) {
30             my $type = shift;
31             my $base = shift;
32              
33             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             my $class = join '::', __PACKAGE__, 'Instance';
48              
49             $type = $mappings->{$type} // 'Data::Object::Universal';
50             $base = $class unless $base;
51              
52             my $format = '%s::__ANON__::%04d';
53             my $package = sprintf $format, $class, ++$serial;
54             my @supers = ("use base '$type'", "use base '$base'");
55              
56             eval join '; ', ("package $package", @supers);
57              
58             croak $@ if $@;
59              
60             return $package;
61             }
62              
63             sub build_clone (@) {
64             my $class = shift;
65             my $args = shift;
66              
67             $args = clone $class->data if not defined $args && ref $class;
68              
69             my $type = deduce_type $class;
70             my $clone = build_class $type, ref($class) || $class;
71              
72             $args = blessed $args ? $args->data : $args;
73              
74             return $clone->new($args);
75             }
76              
77             sub build_object (@) {
78             my $args = shift;
79              
80             my $type = deduce_type $args;
81             my $class = build_class $type;
82              
83             $args = blessed $args ? $args->data : $args;
84              
85             return $class->new($args);
86             }
87              
88             1;
89              
90             __END__