File Coverage

blib/lib/Test/Stream/HashBase.pm
Criterion Covered Total %
statement 55 55 100.0
branch 10 12 83.3
condition 6 8 75.0
subroutine 14 14 100.0
pod 2 3 66.6
total 87 92 94.5


line stmt bran cond sub pod time code
1             package Test::Stream::HashBase;
2 109     109   1029 use strict;
  109         188  
  109         2730  
3 109     109   516 use warnings;
  109         166  
  109         2953  
4              
5 109     109   499 use Carp qw/confess croak/;
  109         189  
  109         5610  
6 109     109   549 use Scalar::Util qw/blessed reftype/;
  109         204  
  109         26077  
7              
8             $Carp::Internal{(__PACKAGE__)}++;
9              
10             my (%META);
11              
12             sub import {
13 4066     4066   13507 my ($class, %args) = @_;
14              
15 4066   66     17981 my $into = $args{into} || caller;
16 4066   100     14539 my $meta = $META{$into} = $args{accessors} || [];
17              
18             # Use the comment to change the filename slightly so that Devel::Cover does
19             # not try to cover the contents of the string eval.
20 4066         6553 my $file = __FILE__;
21 4066         82630 $file =~ s/(\.*)$/.eval$1/;
22 4066         11356 my $eval = "# line 1 \"$file\"\npackage $into;\n";
23              
24 4066 100       12026 if(my $base = $args{base}) {
25 2565   66     7488 my $bmeta = $META{$base} || croak "Base class '$base' is not a HashBase class";
26              
27 2563         18524 $eval .= "sub " . uc($_) . "() { '$_' };\n" for @$bmeta;
28              
29 109     109   562 no strict 'refs';
  109         189  
  109         19247  
30 2563 50       32140 push @{"$into\::ISA"} => $base
  2563         31211  
31             unless $into->isa($base);
32             }
33              
34             {
35 4064         9163 $eval .= join '' => map {
36 4064         7969 my $const = uc($_);
  14390         21233  
37             <<" EOT"
38             sub $const() { '$_' }
39             sub $_ { \$_[0]->{'$_'} }
40             sub set_$_ { \$_[0]->{'$_'} = \$_[1] }
41             sub clear_$_ { delete \$_[0]->{'$_'} }
42             EOT
43 14390         68452 } @$meta;
44             }
45              
46 4064 50       1622457 eval "${eval}1;" || die $@;
47              
48 4064 100       85641 return if $args{no_new};
49              
50 109     109   553 no strict 'refs';
  109         190  
  109         38961  
51 3969         7172 *{"$into\::new"} = \&_new;
  3969         1330512  
52             }
53              
54             sub _new {
55 16897     16897   55907 my ($class, %params) = @_;
56 16897         32493 my $self = bless \%params, $class;
57 16897 100       105536 $self->init if $self->can('init');
58 16860         58057 $self;
59             }
60              
61             sub gen_accessor {
62 50     50 1 623 my $class = shift;
63 50         83 my ($field) = @_;
64             sub {
65 168     168   465 my $self = shift;
66 168 100       491 ($self->{$field}) = @_ if @_;
67 168         759 $self->{$field};
68 50         256 };
69             }
70              
71             sub gen_getter {
72 7     7 1 14 my $class = shift;
73 7         12 my ($field) = @_;
74 7     9   51 sub { $_[0]->{$field} };
  9         46  
75             }
76              
77             sub gen_setter {
78 7     7 0 14 my $class = shift;
79 7         12 my ($field) = @_;
80 7     8   43 sub { $_[0]->{$field} = $_[1] };
  8         37  
81             }
82              
83             1;
84              
85             __END__