File Coverage

blib/lib/OOP/Perlish/Class/Accessor.pm
Criterion Covered Total %
statement 314 335 93.7
branch 195 236 82.6
condition 47 75 62.6
subroutine 51 54 94.4
pod 17 17 100.0
total 624 717 87.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             # $Id$
3             # $Author$
4             # $HeadURL$
5             # $Date$
6             # $Revision$
7 6     6   51 use warnings;
  6         10  
  6         195  
8 6     6   31 use strict;
  6         10  
  6         337  
9             {
10              
11             package OOP::Perlish::Class::Accessor;
12             our $VERSION = 0.0100;
13 6     6   48 use warnings;
  6         12  
  6         225  
14 6     6   46 use strict;
  6         13  
  6         206  
15 6     6   35 use Scalar::Util qw(weaken blessed);
  6         27  
  6         1053  
16 6     6   39 use Carp qw(confess);
  6         8  
  6         297  
17 6     6   13504 use Data::Dumper;
  6         17555  
  6         340  
18 6     6   3286 use OOP::Perlish::Class::Abstract; # for implementation method exclusion
  6         14  
  6         169  
19              
20             ##########************************************************************************##########
21             #!!!!!!!!! BEGIN Inherit constructor from OOP::Perlish::Class; and overload methods associated
22             #!!!!!!!!! with accessors (because we are accessors...)
23             ##########************************************************************************##########
24              
25             ############################################################################################
26             ## We override ____OOP_PERLISH_CLASS_REQUIRED_FIELDS, _accessors, ___inherit_accessors, and
27             ## ___OOP_PERLISH_CLASS__ACCESSORS below
28             ############################################################################################
29 6     6   33 use base 'OOP::Perlish::Class';
  6         9  
  6         18362  
30              
31             ############################################################################################
32             ## We must override __OOP_PERLISH_CLASS__REQUIRED_FIELDS because we will not initialize required fileds
33             ## via _accessors in the normal way
34             ############################################################################################
35             sub ____OOP_PERLISH_CLASS_REQUIRED_FIELDS
36             {
37 364     364   2338 return ( [qw(name type)] );
38             }
39              
40             ############################################################################################
41             ## We are accessors, we cannot inherit them
42             ############################################################################################
43             sub ____inherit_accessors
44             {
45 91     91   249 return;
46             }
47              
48             ############################################################################################
49             ## We are accessors, we cannot have accessors.
50             ############################################################################################
51             sub ____OOP_PERLISH_CLASS_ACCESSORS
52             {
53 181     181   1168 return {};
54             }
55              
56             ############################################################################################
57             ## We are accessors, we cannot have accessors.
58             ############################################################################################
59             sub _accessors
60             {
61 0     0   0 return;
62             }
63              
64             ##########************************************************************************##########
65             #!!!!!!!!! END overloads/inheritance from OOP::Perlish::Class
66             ##########************************************************************************##########
67              
68             ############################################################################################
69             ## get/set the value stored in this accessor.
70             ############################################################################################
71             sub value
72             {
73 290     290 1 671 my ( $self, @values ) = @_;
74              
75 290 50 33     1005 if( @values && ( $self->readonly() && $self->self()->{__initialized} ) ) {
      66        
76 0         0 carp( 'Cannot set ' . $self->name() . 'With ' . Dumper( \@values ) . 'Because it is readonly and we\'re already initialized' );
77             }
78              
79 290 100       775 if(@values) {
80 130         416 $self->__set_value(@values);
81             }
82 290         1022 return $self->__get_value();
83             }
84              
85             ############################################################################################
86             ## determine if a value (even undef) has been set on this accessor for a specific instance
87             ############################################################################################
88             sub is_set
89             {
90 388     388 1 445 my ($self) = @_;
91 388 100       669 return( (defined($self->self()->{___fields}->{ $self->name() }->{_Set})) ? $self->self()->{___fields}->{ $self->name() }->{_Set} : -1 );
92             }
93              
94             ############################################################################################
95             ## get/set whether this should be treated as readonly after initialization
96             ############################################################################################
97             sub readonly
98             {
99 260     260 1 623 my ( $self, $readonly ) = @_;
100              
101 260 50 33     643 if( defined($readonly) && !exists( $self->{_readonly} ) ) {
102 0         0 $self->{_readonly} = $readonly;
103             }
104 260 50       1144 $self->{_readonly} = undef unless( $self->{_readonly} );
105 260         1054 return $self->{_readonly};
106             }
107              
108             ############################################################################################
109             ## get/set the type of the data stored in this
110             ############################################################################################
111             sub type
112             {
113 1808     1808 1 2366 my ( $self, $type ) = @_;
114 1808         126739 $type = uc($type);
115 1808 100       5649 if($type) {
116 89 100       276 confess("Invalid type specified") unless( $self->__valid_type_lookup($type) );
117              
118 88 50       269 if( !$self->{_Type} ) {
119 88         204 $self->{_Type} = $type;
120 88         281 $self->base_type($type);
121             }
122             }
123 1807 50       11878 return $self->{_Type} if( defined( $self->{_Type} ) );
124 0         0 return;
125             }
126              
127             ############################################################################################
128             ## get/set '$self' of this accessor to be used by ->validator() subroutines that need to see the class
129             ## for which we are an accessor of, rather than this accessor class itself.
130             ## In principal, this should only be set by the class which defines this accessor, but this is not enforced.
131             ############################################################################################
132             sub self
133             {
134 1914     1914 1 2496 my ( $self, $class_self ) = @_;
135              
136 1914 100       4242 if( defined $class_self ) {
137 305 50 33     1991 confess('argument to ->self() is not a blessed reference') unless( ref($class_self) && blessed($class_self) );
138              
139 305         845 weaken($class_self); # weaken to avoid cyclic reference leaks
140 305 50       881 $self->{_class_self} = $class_self if( defined($class_self) );
141             }
142 1914 50       8061 return $self->{_class_self} if( defined( $self->{_class_self} ) );
143 0         0 return;
144             }
145              
146             ############################################################################################
147             ## get/set the name of this accessor
148             ############################################################################################
149             sub name
150             {
151 1620     1620 1 2451 my ( $self, $name ) = @_;
152              
153 1620 100       2981 if( defined($name) ) {
154 89         224 $self->{_name} = $name;
155             }
156 1620 50       8613 return $self->{_name} if( defined( $self->{_name} ) );
157 0         0 return;
158             }
159              
160             ############################################################################################
161             ## get/set whether this is a required attribute to the constructor
162             ############################################################################################
163             sub required
164             {
165 69     69 1 105 my ( $self, $required ) = @_;
166              
167 69 100       158 if( defined($required) ) {
168 8         19 $self->{_required} = $required;
169             }
170 69 100       267 return $self->{_required} if( defined( $self->{_required} ) );
171 44         157 return;
172             }
173              
174             ############################################################################################
175             ## get/set the default value
176             ############################################################################################
177             sub default ## no critic (ProhibitBuiltinHomonyms)
178             {
179 30     30 1 63 my ( $self, @values ) = @_;
180              
181 30 100 100     103 if( @values && !$self->default_is_set() ) {
182 10         22 $self->{_default_is_set} = 1;
183 10 50 33     28 if( !defined( $values[0] ) && scalar @values == 1 ) {
184 0         0 $self->{_default} = undef;
185 0         0 return;
186             }
187 10         29 ( $self->{_default} ) = $self->reference( $self->__dereference_always(@values) );
188             }
189 30 50       81 if( defined( $self->{_default} ) ) {
190 30         75 return $self->dereference( $self->{_default} );
191             }
192              
193 0         0 return;
194             }
195              
196             ############################################################################################
197             ## Specify whether we will permit direct mutation of this reference
198             ############################################################################################
199             sub mutable
200             {
201 62     62 1 107 my ($self, $mutable) = @_;
202              
203 62 100       150 if(defined($mutable)) {
204 2         7 $self->{_mutable} = $mutable;
205             }
206              
207 62 100       175 if(defined($self->{_mutable})) { # && $self->type() && $self->type() =~ m/REF/i) {
208 8         25 return $self->{_mutable};
209             }
210 54         152 return 0;
211             }
212              
213             ############################################################################################
214             ## Check if default value has been set
215             ############################################################################################
216             sub default_is_set
217             {
218 52     52 1 72 my ($self) = @_;
219              
220 52         595 return $self->{_default_is_set};
221             }
222              
223             ############################################################################################
224             ## get the basetype of either the type of this object, or the type passed as an argument
225             ############################################################################################
226             sub base_type
227             {
228 273     273 1 400 my ( $self, $type ) = @_;
229 273   66     803 $type ||= $self->type();
230              
231 273 50       743 return $self->__valid_type_lookup($type) if( $self->__valid_type_lookup($type) );
232             }
233              
234             ############################################################################################
235             ## based on the type, and basetype of this object, dereferences (if necessary) the data
236             ## so that the requester obtains what they expect.
237             ############################################################################################
238             sub dereference
239             {
240 283     283 1 402 my ( $self, $ref ) = @_;
241              
242 283         609 for( $self->type() ) {
243 283 100       1136 /REF/i && do {
244             ## Re-reference with temporary storage to protect encapsulation unless defined as mutable
245 60 100       197 if(! $self->mutable()) {
246 54 100 66     240 /HASH/ && ref($ref) eq 'HASH' && do {
247 18         23 my %tmp = ( %{ $ref } );
  18         92  
248 18         157 return \%tmp;
249             };
250 36 100 66     154 /ARRAY/ && ref($ref) eq 'ARRAY' && do {
251 15         19 my @tmp = ( @{ $ref } );
  15         45  
252 15         97 return \@tmp;
253             };
254 21 100 66     105 /SCALAR/ && ref($ref) eq 'SCALAR' && do {
255 15         20 my $tmp = ${$ref};
  15         25  
256 15         93 return \$tmp;
257             };
258             }
259 12         81 return $ref;
260             };
261 223 100       522 /CODE/i && do {
262 17         86 return $ref;
263             };
264 206 100       5618 /OBJECT/ && do {
265 21         146 return $ref;
266             };
267 185 100       619 /HASH/ && do {
268 28 50       86 return %{$ref} if( ref($ref) eq 'HASH' );
  28         168  
269             };
270 157 100       320 /ARRAY/ && do {
271 28 50       83 return @{$ref} if( ref($ref) eq 'ARRAY' );
  28         151  
272             };
273 129 100       325 /SCALAR/ && do {
274 119 50       303 return ${$ref} if( ref($ref) eq 'SCALAR' );
  119         830  
275             };
276             }
277 10         61 return $ref;
278             }
279              
280             ############################################################################################
281             ## based on the basetype and type of this object, created a reference to it for insertion into $self
282             ############################################################################################
283             sub reference
284             {
285 181     181 1 379 my ( $self, @stuff ) = @_;
286              
287 181         397 for( $self->type() ) {
288 181 100       880 /^REF/ && do {
289 8         46 return $stuff[0];
290             };
291 173 100       527 /CODE/i && do {
292 6         27 return $stuff[0];
293             };
294 167 100       398 /GLOB/ && do {
295 4         23 return $stuff[0];
296             };
297 163 100       470 /REGEXP/i && do {
298 3         22 return $stuff[0];
299             };
300 160 100       411 /OBJECT/ && do {
301 17         78 return $stuff[0];
302             };
303 143 100       355 /HASH/ && do {
304 32         231 return { (@stuff) };
305             };
306 111 100       301 /ARRAY/ && do {
307 26         122 return \@stuff;
308             };
309 85 50       235 /SCALAR/ && do {
310 85         349 return \$stuff[0];
311             };
312             }
313 0         0 return; @stuff;
  0         0  
314             }
315              
316             ############################################################################################
317             ## set/get the validator sub-routine used for set operations of this accessor
318             ############################################################################################
319             sub validator
320             {
321 455     455 1 692 my ( $self, $validator ) = @_;
322              
323 455 100 66     1264 if( $validator && ref($validator) ) {
324 45         502 for( ref($validator) ) {
325 45 100       188 /CODE/i && do {
326 11         56 return ( $self->{_Validator} = $validator );
327             };
328 34 50       215 /REGEXP/i && do {
329 34         132 return ( $self->{_Validator} = $self->__regexp_sub_factory($validator) );
330             };
331             }
332 0     0   0 return ( $self->{_Validator} = sub {return} );
  0         0  
333             }
334             else {
335 410         1227 return $self->{_Validator};
336             }
337             }
338              
339             ############################################################################################
340             ## get/set the classes an object must "is-a" to be valid as a value for this accessor
341             ############################################################################################
342             sub object_isa
343             {
344 55     55 1 132 my ( $self, $classes ) = @_;
345              
346 55 100       900 if($classes) {
347 2 50       10 $classes = [$classes] unless( ref($classes) );
348 2         4 $self->{_Object_Classes} = [ @{$classes} ];
  2         9  
349             }
350 55 100       229 return @{ $self->{_Object_Classes} } if( defined( $self->{_Object_Classes} ) );
  14         49  
351             }
352              
353             ############################################################################################
354             ## get/set the methods an object must "can" to be valid as a value for this accessor
355             ############################################################################################
356             sub object_can
357             {
358 60     60 1 90 my ( $self, $interfaces ) = @_;
359              
360 60 100       122 if($interfaces) {
361 6 50       20 $interfaces = [$interfaces] unless( ref($interfaces) );
362 6         10 $self->{_Object_Interfaces} = [ @{$interfaces} ];
  6         28  
363             }
364 60 100       219 return @{ $self->{_Object_Interfaces} } if( defined( $self->{_Object_Interfaces} ) );
  24         75  
365             }
366              
367             ############################################################################################
368             ## get/set the classes (packages) that an object must be like
369             ############################################################################################
370             sub implements
371             {
372 58     58 1 77 my ( $self, $classes ) = @_;
373              
374 58 100       134 if($classes) {
375 4 50       25 $classes = [$classes] unless( ref($classes) );
376 4         7 $self->{_Object_Implements} = [ @{$classes} ];
  4         23  
377             }
378 58 100       236 return @{ $self->{_Object_Implements} } if( defined( $self->{_Object_Implements} ) );
  28         98  
379             }
380              
381             ##########************************************************************************##########
382             #!!!!!!!!! Internal foo
383             ##########************************************************************************##########
384              
385             ############################################################################################
386             ## Lookup a type and determin if its a) valid, and b) if it has a basetype
387             ############################################################################################
388             sub __valid_type_lookup
389             {
390 635     635   905 my ( $self, $type ) = @_;
391              
392 635         3623 my %valid_types_map = (
393             SCALAR => 'SCALARREF',
394             ARRAY => 'ARRAYREF',
395             HASH => 'HASHREF',
396             CODE => 'CODEREF',
397             REF => 'REF',
398             GLOB => 'GLOBREF',
399             OBJECT => 'OBJECT',
400             Regexp => 'REGEXP',
401             # TODO: CLASS => 'CLASS',
402             );
403 635         4245 my %valid_types_lut = reverse %valid_types_map;
404              
405 635 100       3033 if( exists( $valid_types_map{$type} ) ) {
    100          
406 406         3346 return $type;
407             }
408             elsif( exists( $valid_types_lut{$type} ) ) {
409 228         1851 return $valid_types_lut{$type};
410             }
411             else {
412 1         256 return;
413             }
414             }
415              
416             ############################################################################################
417             ## Verify that a value specified as a default is valid for the accessor; this allows post-validation in object instantiation
418             ############################################################################################
419             sub __validate_default
420             {
421 58     58   96 my ($self) = @_;
422              
423 58 100 66     281 return unless( exists( $self->{_default} ) && $self->default_is_set() );
424              
425 10         34 my @orig_values = $self->__dereference_always( $self->{_default} );
426 10         37 my @valid_values = $self->__validate( $self->{_default} );
427              
428 10 100       29 if( !@valid_values ) {
429 5 50       41 confess( 'Invalid default value ' . ( (@orig_values) ? Dumper( \@orig_values ) : '`undef\'' ) . ' for field ' . $self->name() );
430             }
431              
432 5         14 $self->{_default} = $self->reference(@valid_values);
433 5         24 return;
434             }
435              
436             ############################################################################################
437             ## Jump through requisite hoops to set a value; marking _Set appropriately for is_set method
438             ############################################################################################
439             sub __set_value
440             {
441 130     130   241 my ( $self, @values ) = @_;
442              
443 130 50 33     482 if( @values && !( $self->readonly() && $self->self()->{__initialized} ) ) {
      33        
444             ## Handle explicit setting to undef; bypass validation, bypass everything.
445 130         477 $self->self()->{___fields}->{ $self->name() }->{_Set} = 1;
446 130 50 33     456 if( !defined( $values[0] ) && scalar @values == 1 ) {
447 0         0 $self->self()->{___fields}->{ $self->name() }->{_Value} = undef;
448 0         0 return;
449             }
450 130 100       457 $self->self()->{___fields}->{ $self->name() }->{_Set} = 0 unless($self->__validate(@values));
451 130         427 $self->self()->{___fields}->{ $self->name() }->{_Value} = $self->reference( $self->__validate(@values) );
452             }
453 130         401 return;
454             }
455              
456             ############################################################################################
457             ## return empty references if our type is a *REF
458             ############################################################################################
459             sub __appropriate_undef_value
460             {
461 77     77   125 my ($self) = @_;
462 77 100       156 if($self->type() =~ m/REF/) {
    100          
463 36         102 return $self->reference();
464             }
465             elsif($self->type() eq 'SCALAR') {
466 9         48 return undef;
467             }
468             else {
469 32         196 return( () );
470             }
471             }
472            
473              
474             ############################################################################################
475             ## Jump through requisite hoops to obtain a value; either set or default
476             ############################################################################################
477             sub __get_value
478             {
479 290     290   428 my ($self) = @_;
480              
481 290 100 66     661 if($self->is_set() == 1 ) {
    100          
    100          
    50          
482 208 50       407 if( ! defined( $self->self()->{___fields}->{ $self->name() }->{_Value} ) ) {
483 0         0 return $self->__appropriate_undef_value();
484             } else {
485 208         391 return $self->dereference( $self->self()->{___fields}->{ $self->name() }->{_Value} );
486             }
487             }
488             elsif( $self->is_set() == 0 ) {
489 67         172 return $self->__appropriate_undef_value();
490             }
491             elsif( $self->is_set() == -1 && ! $self->default_is_set() ) {
492 10         37 return $self->__appropriate_undef_value();
493             }
494             elsif( $self->default_is_set() ) {
495 5 50       10 return $self->__appropriate_undef_value() unless(defined( $self->default() ) );
496 5         12 return $self->default();
497             }
498 0         0 return $self->reference();
499             }
500              
501              
502             ############################################################################################
503             ## Perform the extra validation required of objects (polymorphism/inheritance)
504             ############################################################################################
505             sub __validate_obj_type
506             {
507 49     49   80 my ( $self, $thing ) = @_;
508              
509 49 100       139 return unless( ref($thing) );
510 47 50       191 return unless( blessed($thing) );
511              
512 47 100       152 if( $self->object_isa() ) {
513 6         15 for my $class ( $self->object_isa() ) {
514 6 100       76 return unless( $thing->isa($class) );
515             }
516             }
517 45 100       135 if( $self->object_can() ) {
518 9         24 for my $method ( $self->object_can() ) {
519 17 100       133 return unless( $thing->can($method) );
520             }
521             }
522 42 100       114 if( $self->implements() ) {
523 12         79 for my $class ( $self->implements() ) {
524 12 100       41 return unless( $self->__validate_class_implementation( $class, $thing ) );
525             }
526             }
527 38         118 return 1;
528             }
529              
530             ############################################################################################
531             ## Verify that a class implements interfaces (excluding interfaces from OOP::Perlish::Class itself)
532             ############################################################################################
533             sub __validate_class_implementation
534             {
535 12     12   32 my ( $self, $class, $thing ) = @_;
536              
537 12         18 my @interfaces;
538              
539 6     6   58 no strict 'refs';
  6         13  
  6         641  
540 12 50       19 if( scalar keys %{ '::' . $class . '::' } == 0 ) {
  12         80  
541 0         0 eval "require $class";
542 0 0       0 confess("$@") if("$@");
543             }
544 6     6   36 use strict;
  6         13  
  6         9267  
545              
546             ### XXX: Hash slice assignment for lookup
547 12         18 my %oop_perlish_class_interfaces;
548 12         83 @oop_perlish_class_interfaces{ OOP::Perlish::Class::Abstract->new()->_all_methods() } = undef;
549              
550 12         165 my $class_ref = bless( {}, $class );
551              
552 12 100       98 if( $class_ref->can('_all_methods') ) {
553 6         18 @interfaces = grep { ! exists( $oop_perlish_class_interfaces{$_} ) } $class_ref->_all_methods();
  384         676  
554             }
555             else {
556 6         34 @interfaces = grep { ! exists( $oop_perlish_class_interfaces{$_} ) } $self->_all_methods($class);
  438         3681  
557             }
558 12 50       92 confess("No interfaces from $class") unless(@interfaces);
559              
560 12         26 for my $method (@interfaces) {
561 276 100       1131 return unless( $thing->can($method) );
562             }
563 8         114 return 1;
564             }
565              
566             ############################################################################################
567             ## Verify that the underlying type of a reference is correct for the type of this accessor
568             ############################################################################################
569             sub __validate_ref_type
570             {
571 102     102   171 my ( $self, $thing ) = @_;
572              
573 102 100       193 if( $self->type() eq 'OBJECT' ) {
574 49 100       146 return unless( $self->__validate_obj_type($thing) );
575             }
576             else {
577 53 100       161 return unless( ref($thing) eq $self->base_type() );
578             }
579 76         354 return 1;
580             }
581              
582             ############################################################################################
583             ## Validate that the type of the thing passed to this object is a valid type for our storage.
584             ############################################################################################
585             sub __validate_type
586             {
587 270     270   473 my ( $self, @values ) = @_;
588              
589             ## Don't validate_ref_type for REF type (backwards sounding I know; but if we are a REF type, we don't care about the underlying _type_)
590             ## We also cannot fail an array, unfortunately, because it could be an array containing one member, a reference to something...
591 270 100 66     1032 if( ( ref( $values[0] ) && scalar(@values) == 1 ) && $self->type() !~ m/(?:^REF|ARRAY)/ ) {
      100        
592 63 100       435 return unless( $self->__validate_ref_type( $values[0] ) );
593             }
594              
595 253 100 100     586 if( $self->type() =~ m/REF|CODE|REGEXP|OBJECT/ && $self->type() !~ m/(?:^REF|SCALAR|ARRAY|HASH)/ ) {
596 39 100 66     138 return unless( $self->__validate_ref_type( $values[0] ) && scalar(@values) == 1 );
597             }
598              
599 244         630 for( $self->type() ) {
600 244 100 66     681 /^REF/ && do { return unless( scalar @values == 1 && ref( $values[0] ) ); };
  8 100       60  
601 242 50 66     596 /HASH/ && do { return unless( scalar @values % 2 == 0 || ref( $values[0] ) eq 'HASH' ); };
  34 100       171  
602 242 100       580 /SCALAR/ && do { return unless( scalar @values == 1 ); };
  134 100       326  
603 238 50 33     810 /GLOB/ && do { return unless( scalar @values == 1 && ref( $values[0] ) eq 'GLOB' ) };
  2 100       17  
604             }
605              
606 238         756 return 1;
607             }
608              
609             ############################################################################################
610             ## Test the validity of data using the validator of this accessor
611             ############################################################################################
612             sub __validate
613             {
614 270     270   515 my ( $self, @values ) = @_;
615              
616 270 50       535 return unless(@values);
617 270 100       626 return unless( $self->__validate_type(@values) );
618              
619 238 100       760 if( defined( $self->validator() ) ) {
620 172         353 return $self->validator()->( $self->self(), $self->__dereference_always(@values) );
621             }
622             else {
623 66         193 return $self->__dereference_always(@values);
624             }
625             }
626              
627             ############################################################################################
628             ## This will indescriminately dereference a type to its base type; it is used because it simplifies validation
629             ############################################################################################
630             sub __dereference_always
631             {
632 258     258   525 my ( $self, @input ) = @_;
633              
634 258         342 my @values = ();
635              
636 258 100 100     1656 if( scalar @input == 1 && ref( $input[0] ) && ref( $input[0] ) eq $self->base_type() ) {
      100        
637 45         104 my $tmp_type = $self->type();
638 45         127 my $buf_type = $self->base_type();
639              
640 45         91 $self->{_Type} = $buf_type;
641 45         139 @values = $self->dereference( $input[0] );
642 45         120 $self->{_Type} = $tmp_type;
643             }
644             else {
645 213         452 @values = @input;
646             }
647 258         967 return @values;
648             }
649              
650             ############################################################################################
651             ## Return a subroutine which will correctly validate via regexp the data of the specified type.
652             ############################################################################################
653             sub __regexp_sub_factory
654             {
655 34     34   57 my ( $self, $regexp ) = @_;
656              
657 34         39 my $possible_method;
658 34         73 $possible_method = '__regexp_sub_impl_' . lc( $self->type() );
659              
660 34 100       216 if( $self->can($possible_method) ) {
661 29         94 return $self->$possible_method($regexp);
662             }
663              
664 5         17 $possible_method = '__regexp_sub_impl_' . lc( $self->base_type() );
665 5 50       31 if( $self->can($possible_method) ) {
666 5         19 return $self->$possible_method($regexp);
667             }
668 0     0   0 return sub {return};
  0         0  
669             }
670              
671             ############################################################################################
672             ## "free" regexp subroutine for hashes
673             ############################################################################################
674             sub __regexp_sub_impl_hash
675             {
676 8     8   18 my ( $self, $regexp ) = @_;
677              
678             return sub {
679 14     14   56 my ( $this, %args ) = @_;
680              
681 14         21 my $re = $regexp;
682 14         26 my %valid_args = ();
683 14 50       48 return unless( keys %args );
684 14         50 while( my ( $key, $val ) = each %args ) {
685 34 100       289 $val =~ /($re)/ && do {
686 21         112 $valid_args{$key} = $1;
687             }
688             }
689 14 100       111 return %valid_args if( scalar keys %args == scalar keys %valid_args );
690 5         30 return;
691 8         113 };
692             }
693              
694             ############################################################################################
695             ## "free" regexp subroutine for arrays
696             ############################################################################################
697             sub __regexp_sub_impl_array
698             {
699 6     6   14 my ( $self, $regexp ) = @_;
700              
701             return sub {
702 10     10   27 my ( $this, @args ) = @_;
703              
704 10         17 my $re = $regexp;
705 10         17 my @valid_args = ();
706 10 50       27 return unless(@args);
707 10         21 for(@args) {
708 30 50       62 return unless( defined($_) );
709 30 100       218 /($re)/x && do {
710 17         56 push @valid_args, $1;
711             };
712             }
713 10 100       55 return @valid_args if( scalar @args == scalar @valid_args );
714 5         25 return;
715 6         83 };
716             }
717              
718             ############################################################################################
719             ## "free" regexp subroutine for scalar
720             ############################################################################################
721             sub __regexp_sub_impl_scalar
722             {
723 18     18   29 my ( $self, $regexp ) = @_;
724              
725             return sub {
726 92     92   131 my ( $this, $arg ) = @_;
727 92         99 my $re = $regexp;
728 92         98 my $valid_arg = undef;
729              
730 92 50       222 return unless( defined($arg) );
731 92 100       909 $arg =~ m/($re)/ && do {
732 87         201 $valid_arg = $1;
733 87 50       169 return unless( defined($valid_arg) );
734 87         349 return $valid_arg;
735             };
736 5         23 return;
737 18         259 };
738             }
739              
740             ############################################################################################
741             ## "free" regexp subroutine for objects (uses ref for string representation)
742             ############################################################################################
743             sub __regexp_sub_impl_object
744             {
745 2     2   6 my ( $self, $regexp ) = @_;
746              
747             return sub {
748 4     4   7 my ( $this, $obj ) = @_;
749              
750 4 50       11 return unless( defined $obj );
751 4 100       221 return $obj if( ref($obj) =~ m/$regexp/ );
752 2         8 return;
753 2         19 };
754             }
755             }
756             1;
757             __END__