File Coverage

lib/Badger/Data.pm
Criterion Covered Total %
statement 18 26 69.2
branch 8 20 40.0
condition 5 11 45.4
subroutine 6 10 60.0
pod 9 9 100.0
total 46 76 60.5


line stmt bran cond sub pod time code
1             #========================================================================
2             #
3             # Badger::Data
4             #
5             # DESCRIPTION
6             # Base class module for objects representing various different data
7             # types.
8             #
9             # AUTHOR
10             # Andy Wardley
11             #
12             #========================================================================
13              
14             package Badger::Data;
15              
16             use Badger::Class
17 1         7 version => 0.01,
18             debug => 0,
19             base => 'Badger::Prototype',
20             import => 'class CLASS',
21             utils => 'md5_hex self_params refaddr',
22             auto_can => 'method', # anything in $METHODS can become a method
23             constants => 'HASH TRUE FALSE',
24             constant => {
25             # tell Badger what class to strip off to generate id()
26             base_id => __PACKAGE__,
27             id => 'type',
28             },
29             alias => {
30             # alias type() to id() method provided by Badger::Base
31             type => 'id',
32 1     1   453 };
  1         2  
33              
34              
35             # Define a lexical scope with a $METADATA table for storing any out-of-band
36             # information about text objects. The methods defined below can be called
37             # as subroutines (as part of the vmethod mechanism), so the first argument
38             # can be a non-reference text string in place of the usual $self object
39             # reference (which itself is just a blessed reference to a scalar text
40             # string). To handle this case, we use an md5_hex encoding of the text
41             # to determine a unique handle for it (or close enough to unique for
42             # practical purposes)
43              
44             {
45             my $METADATA = { };
46            
47             sub metadata {
48             my $meta = $METADATA->{
49 6 50 33 6 1 44 $_[0] && ref $_[0]
      100        
50             ? refaddr $_[0]
51             : md5_hex $_[0]
52             } ||= { };
53              
54             # short-cut: return metadata hash when called without arguments
55 6 100       20 return $meta if @_ == 1;
56              
57             # short-cut: return item in the metadata hash when called with a
58             # single (non-hashref) item
59 3 100 66     17 return $meta->{ $_[1] } if @_ == 2 && ref $_[1] ne HASH;
60            
61             # add metadata items when called with a HASH ref or multiple args
62 1         4 my ($self, $params) = self_params(@_);
63 1         4 @$meta{ keys %$params } = values %$params;
64 1         5 return $meta;
65             }
66             }
67              
68             # This is a throwback to the Template::TT3::Type object on which this is
69             # based... these methods probably won't be staying here - they should be
70             # in Badger::Data::Type
71              
72             our $METHODS = {
73             method => \&method, # TODO: can() as alias to method()?
74             methods => \&methods,
75             type => \&type,
76             ref => \&ref,
77             def => \&defined,
78             undef => \&undefined,
79             defined => \&defined,
80             undefined => \&undefined,
81             true => \&true,
82             false => \&false,
83             };
84              
85              
86             sub init {
87 4     4 1 10 my ($self, $config) = @_;
88              
89             # merge everything in $config into $self for now
90 4         16 @$self{ keys %$config } = values %$config;
91            
92             # merge all config methods with class $METHODS
93             $self->{ methods } = $self->class->hash_vars(
94             METHODS => $config->{ methods }
95 4         11 );
96            
97 4         12 return $self;
98             }
99              
100              
101             sub method {
102 2     2 1 8 my $self = shift->prototype;
103            
104             # return item from hash or the hash itself when called without arguments
105             return @_
106             ? $self->{ methods }->{ $_[0] }
107 2 100       10 : $self->{ methods };
108             }
109              
110              
111             sub methods {
112 1     1 1 16 my $self = shift->prototype;
113            
114             # return hash ref when called without argument
115 1 50       7 return $self->{ methods } unless @_;
116            
117             # add items to hash when called with hash ref or multiple args
118 0 0 0     0 my $items = @_ == 1 && ref $_[0] eq HASH ? shift : { @_ };
119 0         0 my $hash = $self->{ methods };
120 0         0 @$hash{ keys %$items } = values %$items;
121 0         0 return $hash;
122             }
123              
124              
125             sub ref {
126 3     3 1 15 return CORE::ref($_[0]);
127             }
128              
129              
130             sub defined {
131 0 0   0 1   CORE::defined $_[0] ? TRUE : FALSE;
132             }
133              
134              
135             sub undefined {
136 0 0   0 1   CORE::defined $_[0] ? FALSE : TRUE;
137             }
138              
139              
140             sub true {
141 0 0   0 1   $_[0] ? $_[0] : FALSE;
142             }
143              
144              
145             sub false {
146 0 0   0 1   $_[0] ? FALSE : TRUE;
147             }
148              
149              
150             1;
151              
152             __END__