File Coverage

blib/lib/mcoder.pm
Criterion Covered Total %
statement 95 97 97.9
branch 45 56 80.3
condition n/a
subroutine 21 22 95.4
pod 0 4 0.0
total 161 179 89.9


line stmt bran cond sub pod time code
1             package mcoder;
2              
3             our $VERSION = '0.10';
4              
5 4     4   29119 use strict;
  4         9  
  4         147  
6 4     4   20 use warnings;
  4         6  
  4         105  
7 4     4   20 use Carp;
  4         12  
  4         6373  
8              
9             our $debug;
10              
11             my %mcoder;
12              
13             sub import {
14 12     12   51 shift;
15 12         50 while (@_) {
16 16         18 my $kind=shift;
17 16 100       48 my @kind=(ref $kind eq 'ARRAY') ? @$kind : ($kind);
18 16         24 my $args=shift;
19 16 100       36 my @args=(ref $args eq 'ARRAY') ? @$args : ($args);
20              
21 16         23 for my $k (@kind) {
22 23 50       52 exists $mcoder{$k} or
23             croak "unknow mcoder type '$k'";
24 23         22 &{$mcoder{$k}}($k, @args)
  23         52  
25             }
26             }
27             }
28              
29             sub export_proxy {
30 2     2 0 4 shift;
31 2         2 my $delegate=shift;
32 2         4 my $caller=caller(1);
33 2         10 foreach my $m (@_) {
34 4 50       14 my @m=(ref($m) eq 'HASH') ? %$m : ($m, $m);
35 4         10 while (@m) {
36 4         6 my $name=shift @m;
37 4         6 my $method=shift @m;
38 4 50       27 $method=~/^\w+$/ and $method.='(@_)';
39 4         11 my $def=
40             "sub ${caller}::${name} { shift->$delegate->$method }";
41 4 50       13 carp "mcoder def>> $def" if $debug;
42 4     7   167 eval $def;
  6     5   2009  
  5         832  
43 4 50       128 $@ and croak "proxy method definition failed: $@";
44             }
45             }
46             }
47              
48             sub export_accessor {
49 18     18 0 25 my $type=shift;
50 18         28 my $caller=caller(1);
51 18         26 foreach my $m (@_) {
52 26 50       67 my @m=(ref($m) eq 'HASH') ? %$m : ($m, $m);
53 26         44 while (@m) {
54 26         34 my $name=shift @m;
55 26         37 my $attr=shift @m;
56 26 50       121 $attr=~/^\w+$/ and $attr="{q(".$attr.")}";
57 26         29 my $def;
58             # if ($type eq 'accessor') {
59             # $def="\@_ > 1 ? shift->$attr=\$_[0] : shift->$attr";
60             # }
61             # elsif
62 26 100       109 if ($type eq 'get') {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
63 7         11 $def="\$_[0]->$attr";
64             }
65             elsif ($type eq 'array_get') {
66 1         3 $def="\@{(\$_[0]->$attr)||[]}";
67             }
68             elsif ($type eq 'set') {
69 5         7 $name='set_'.$name;
70 5         10 $def="\$_[0]->$attr=\$_[1]";
71             }
72             elsif ($type eq 'array_set') {
73 2         4 $name='set_'.$name;
74 2         5 $def="my \$t=shift; \$t->$attr=\\\@_";
75             }
76             elsif ($type eq 'bool_set') {
77 3         5 $name='set_'.$name;
78 3         8 $def="\$_[0]->$attr=(\@_>1 ? \$_[1] : 1)";
79             }
80             elsif ($type eq 'calculated') {
81 1         5 $def="my \$t=shift; "
82             ."if (defined \$t->$attr) { \$t->$attr } "
83             ."else { \$t->$attr=\$t->_calculate_$name }";
84             }
85             elsif ($type eq 'array_calculated') {
86 1         4 $def="my \$t=shift; "
87             ."if (defined \$t->$attr) { \@{\$t->$attr} } "
88             ."else { my \@a=\$t->_calculate_$name; \$t->$attr=\\\@a; \@a }";
89             }
90             elsif ($type eq 'delete') {
91 1         1 $name='delete_'.$name;
92 1         4 $def="my \$t=shift; exists \$t->$attr and delete \$t->$attr";
93             }
94             elsif ($type eq 'undef') {
95 1         2 $name='undef_'.$name;
96 1         2 $def="\$_[0]->$attr=undef";
97             }
98             elsif ($type eq 'bool_unset') {
99 3         4 $name='unset_'.$name;
100 3         7 $def="\$_[0]->$attr=undef";
101             }
102             elsif ($type eq 'virtual') {
103 1         3 $def=qq(Carp::croak("undefined virtual method called (".\$_[0]."->$name)"))
104             }
105             else {
106 0         0 die "internal error (unknow type $type)"
107             }
108 26         52 my $def1= "sub ${caller}::${name} { $def }";
109 26 50       49 carp "mcoder def >> $def1" if $debug;
110 26 100   3   1314 eval $def1;
  1 100   2   3  
  4 100   4   21  
  2 100   2   16  
  2     2   13  
  1     0   512  
  2     1   23  
  2     5   12  
  0     2   0  
  1     1   6  
  5     1   14  
  5     5   68  
  3         10  
  2         17  
  1         6  
  1         31  
  1         9  
  1         3  
  1         4  
  1         5  
  5         744  
  5         19  
  2         9  
  3         17  
111 26 50       330 $@ and croak "$type method definition failed $@";
112             }
113             }
114             }
115              
116             sub export_new {
117 3     3 0 3 shift;
118 5         44 my $caller=caller(1);
119 5         14 foreach my $name (@_) {
120 6         50 my $def="sub ${caller}::${name} { my \$c=shift; "
121             ."\@_ & 1 "
122             ."and croak q(Odd number of elements passed to constructor); "
123             ."bless {\@_}, \$c }";
124 3 50       12 carp "mcoder def >> $def" if $debug;
125 4         646 eval $def;
126 5 100       75 $@ and croak "constructor method definition failed $@";
127             }
128             }
129              
130             sub export_virtual {
131 3     4 0 122 shift;
132            
133             }
134              
135             %mcoder=( proxy => \&export_proxy,
136             # accesor => \&export_accesor,
137             set => \&export_accessor,
138             array_set => \&export_accessor,
139             get => \&export_accessor,
140             array_get => \&export_accessor,
141             bool_unset => \&export_accessor,
142             bool_set => \&export_accessor,
143             calculated => \&export_accessor,
144             array_calculated => \&export_accessor,
145             delete => \&export_accessor,
146             undef => \&export_accessor,
147             new => \&export_new,
148             virtual => \&export_accessor );
149              
150             1;
151             __END__