File Coverage

blib/lib/JIP/ClassField.pm
Criterion Covered Total %
statement 63 63 100.0
branch 20 22 90.9
condition 6 9 66.6
subroutine 14 14 100.0
pod 0 2 0.0
total 103 110 93.6


line stmt bran cond sub pod time code
1             package JIP::ClassField;
2              
3 1     1   23501 use 5.006;
  1         4  
  1         50  
4 1     1   6 use strict;
  1         3  
  1         42  
5 1     1   5 use warnings;
  1         5  
  1         34  
6 1     1   3 use Carp qw(croak);
  1         2  
  1         59  
7 1     1   3 use English qw(-no_match_vars);
  1         2  
  1         4  
8              
9             our $VERSION = '0.03';
10              
11             # Will be shipping with Perl 5.22
12             my $NAME = eval {
13             require Sub::Util;
14             Sub::Util->can('set_subname');
15             } || sub { $ARG[1] };
16              
17             sub attr {
18 11     11 0 3755 my ($self, $attr, %param) = @ARG;
19              
20 11   66     60 my $class = ref $self || $self;
21              
22 11 100 66     264 croak qq{Class not defined\n}
23             unless defined $class and length $class;
24              
25 10 100 66     199 croak qq{Attribute not defined\n}
26             unless defined $attr and length $attr;
27              
28 9         13 my %patch;
29              
30 9 50       29 if (exists $param{'get'}) {
31 9         20 my ($method_name, $getter) = (q{}, $param{'get'});
32              
33 9 100       30 if ($getter eq q{+}) {
    100          
34 6         10 $method_name = $attr;
35             }
36             elsif ($getter eq q{-}) {
37 2         6 $method_name = q{_}. $attr;
38             }
39             else {
40 1         2 $method_name = $getter;
41             }
42              
43             $patch{$method_name} = sub {
44 9     9   22 my $self = shift;
45 9         41 return $self->{$attr};
46 9         54 };
47             }
48              
49 9 50       30 if (exists $param{'set'}) {
50 9         18 my ($method_name, $setter) = (q{}, $param{'set'});
51              
52 9 100       685 if ($setter eq q{+}) {
    100          
53 6         10 $method_name = q{set_}. $attr;
54             }
55             elsif ($setter eq q{-}) {
56 2         7 $method_name = q{_set_}. $attr;
57             }
58             else {
59 1         1 $method_name = $setter;
60             }
61              
62 9 100       20 if (exists $param{'default'}) {
63 2         6 my $default_value = $param{'default'};
64              
65             $patch{$method_name} = sub {
66 6     6   3278 my $self = shift;
67              
68 6 100       19 if (@ARG == 1) {
69 3         12 $self->{$attr} = shift;
70             }
71             else {
72 3 100       17 $self->{$attr} = ref($default_value) eq 'CODE' ?
73             $default_value->($self) : $default_value;
74             }
75              
76 6         26 return $self;
77 2         10 };
78             }
79             else {
80             $patch{$method_name} = sub {
81 3     3   3636 my ($self, $value) = @ARG;
82 3         38 $self->{$attr} = $value;
83 3         16 return $self;
84 7         47 };
85             }
86             }
87              
88 9         33 return monkey_patch($class, %patch);
89             }
90              
91             sub monkey_patch {
92 11     11 0 36 my ($class, %patch) = @ARG;
93              
94 1     1   764 no strict 'refs';
  1         2  
  1         49  
95 1     1   7 no warnings 'redefine';
  1         1  
  1         160  
96              
97 11         43 while(my ($method_name, $value) = each %patch) {
98 20         40 my $full_name = $class .q{::}. $method_name;
99              
100 20         42 *{$full_name} = $NAME->($full_name, $value);
  20         160  
101             }
102              
103 11         83 return 1;
104             }
105              
106             sub import {
107 2     2   1485 my $caller = caller;
108              
109 2     2   16 return monkey_patch($caller, 'has', sub { attr($caller, @ARG) });
  2         2804  
110             }
111              
112             1;
113              
114             __END__