File Coverage

blib/lib/Aion/Meta/FeatureConstruct.pm
Criterion Covered Total %
statement 39 41 95.1
branch 13 16 81.2
condition 1 3 33.3
subroutine 13 13 100.0
pod 7 7 100.0
total 73 80 91.2


line stmt bran cond sub pod time code
1             package Aion::Meta::FeatureConstruct;
2              
3 6     6   148425 use common::sense;
  6         10  
  6         28  
4              
5 6     6   1173 use Aion::Meta::Util qw//;
  6         9  
  6         5555  
6              
7             Aion::Meta::Util::create_getters(qw/
8             pkg name
9             write read
10             getvar ret
11             /);
12             Aion::Meta::Util::create_accessors(qw/
13             init_arg
14             set get has clear weaken
15             accessor_name reader_name writer_name predicate_name clearer_name
16             initer not_specified
17             getter setter selfret
18             /);
19              
20             # Конструктор
21             sub new {
22 52     52 1 136889 my ($cls, $pkg, $name) = @_;
23              
24 52   33     1124 bless {
25             pkg => $pkg,
26             name => $name,
27             initializer => <<'END',
28             if (exists $value{%(init_arg)s}) {
29             %(initer)s
30             }%(not_specified)s
31             END
32             destroyer => <<'END',
33             if (%(has)s) {
34             eval {
35             %(cleaner)s
36             };
37             warn $@ if $@;
38             }
39             END
40             accessor => <<'END',
41             package %(pkg)s {
42             sub %(accessor_name)s%(attr)s {
43             if (@_>1) {
44             my ($self, $val) = @_;
45             %(setter)s
46             %(selfret)s
47             } else {
48             my ($self) = @_;
49             %(getter)s
50             }
51             }
52             }
53             END
54             reader => <<'END',
55             package %(pkg)s {
56             sub %(reader_name)s {
57             my ($self) = @_;
58             %(read)s
59             }
60             }
61             END
62             writer => <<'END',
63             package %(pkg)s {
64             sub %(writer_name)s {
65             my ($self, $val) = @_;
66             %(write)s
67             %(selfret)s
68             }
69             }
70             END
71             predicate => <<'END',
72             package %(pkg)s {
73             sub %(predicate_name)s {
74             my ($self) = @_;
75             %(has)s
76             }
77             }
78             END
79             clearer => <<'END',
80             package %(pkg)s {
81             sub %(clearer_name)s {
82             my ($self) = @_;
83             if (%(has)s) {
84             %(cleaner)s%(clear)s
85             }
86             %(clearret)s
87             }
88             }
89             END
90             accessor_name => '%(name)s',
91             reader_name => '_get_%(name)s',
92             writer_name => '_set_%(name)s',
93             attr => '',
94             write => '%(preset)s%(set)s%(trigger)s',
95             read => '%(access)s%(getvar)s%(release)s%(ret)s',
96             setter => '%(write)s',
97             getter => '%(read)s',
98             initer => "%(initvar)s%(write)s",
99             init_arg => '%(name)s',
100             initvar => 'my $val = delete $value{%(init_arg)s};',
101             not_specified => '',
102             preset => '',
103             set => '$self->{%(name)s} = $val;',
104             trigger => '',
105             selfret => '$self',
106             access => '',
107             getvar => '%(get)s',
108             get => '$self->{%(name)s}',
109             release => '',
110             ret => '',
111             predicate_name => 'has_%(name)s',
112             has => 'exists $self->{%(name)s}',
113             clearer_name => 'clear_%(name)s',
114             clear => 'delete $self->{%(name)s}',
115             clearret => '$self',
116             cleaner => '',
117             weaken => 'Scalar::Util::weaken(%(get)s);',
118             }, ref $cls || $cls;
119             }
120              
121 5     5 1 4089 sub add_attr { shift->_expand('attr', @_) }
122 32     32 1 3848 sub add_preset { shift->_expand('preset', @_) }
123 3     3 1 3339 sub add_trigger { shift->_expand('trigger', @_) }
124 2     2 1 3368 sub add_cleaner { shift->_expand('cleaner', @_) }
125 8     8 1 3388 sub add_access { shift->_expand('access', @_) }
126             sub add_release {
127 28     28 1 3361 my $self = shift;
128 28 50       101 @$self{qw/getvar ret/} = ('my $val = %(get)s;', '$val') if $self->{ret} eq '';
129 28         60 $self->_expand('release', @_)
130             }
131              
132             sub _expand(@) {
133 78     78   150 my ($self, $key, $code, $shift) = @_;
134              
135 78 100       187 if(ref $self->{$key}) {
    100          
136 1 50       5 if($shift) { unshift @{$self->{$key}}, $code }
  1         2  
  1         4  
137 0         0 else { push @{$self->{$key}}, $code }
  0         0  
138             }
139             elsif ($self->{$key} eq '') {
140 72         99 $self->{$key} = $code;
141             }
142             else {
143 5 100       18 $self->{$key} = $shift? [$code, $self->{$key}]: [$self->{$key}, $code];
144             }
145            
146 78         188 $self
147             }
148              
149             for my $key (qw/initializer destroyer accessor writer reader predicate clearer/) {
150             *$key = sub {
151 120     120   24092 my ($self) = @_;
152 120         291 _idents($self->_resolv($self->{$key}))
153             }
154             }
155              
156             sub _resolv {
157 1788     1788   2037 my ($self, $s) = @_;
158 1788 100       2057 $s = join '', @$s if ref $s;
159 1788         3117 $s =~ s{%\((\w*)\)s}{
160 1668 50       2670 die "has: not construct `$1`\!" unless exists $self->{$1};
161 1668         2277 $self->_resolv($self->{$1})
162             }ge;
163 1788         4039 $s
164             }
165              
166             sub _idents {
167 120     120   168 local ($_) = @_;
168 120         148 my $indent;
169 120         338 s{(^\t*)|;[\t ]*(\S)}{
170 1124 100       1425 if(defined $1) { $indent = $1 } else { ";\n$indent$2" }
  951         3713  
  173         1154  
171             }gme;
172 120         434 $_
173             }
174              
175             1;
176              
177             __END__