File Coverage

lib/Class/Dot/Meta/Accessor/Constrained.pm
Criterion Covered Total %
statement 47 63 74.6
branch 11 22 50.0
condition n/a
subroutine 16 18 88.8
pod 3 3 100.0
total 77 106 72.6


line stmt bran cond sub pod time code
1             # $Id$
2             # $Source$
3             # $Author$
4             # $HeadURL$
5             # $Revision$
6             # $Date$
7             package Class::Dot::Meta::Accessor::Constrained;
8 16     16   113251 use base 'Class::Dot::Meta::Accessor::Overrideable';
  16         41  
  16         11275  
9              
10 16     16   108 use strict;
  16         35  
  16         439  
11 16     16   81 use warnings;
  16         30  
  16         411  
12 16     16   81 use version;
  16         29  
  16         74  
13 16     16   1144 use 5.00600;
  16         49  
  16         1292  
14              
15             our $VERSION = qv('2.0.0_15');
16             our $AUTHORITY = 'cpan:ASKSH';
17              
18 16     16   84 use Carp qw(confess croak);
  16         28  
  16         8561  
19 16     16   250 use Scalar::Util qw(blessed);
  16         34  
  16         746  
20 16     16   115 use overload ();
  16         35  
  16         408  
21              
22 16     16   89 use Class::Dot::Devel::Sub::Name qw(subname);
  16         33  
  16         86  
23              
24 16     16   88 use Class::Dot::Meta::Type qw(_NEWSCHOOL_TYPE _OLDSCHOOL_TYPE);
  16         27  
  16         88  
25              
26             my $CONSTRAINT_CHECK_ERROR = <<'FORMATEOF'
27             Attribute (%s) does not pass the type constraint (%s) with '%s'.;
28             FORMATEOF
29             ;
30              
31             sub register_plugin {
32             return {
33 16     16 1 550 name => 'Constrained',
34             class => __PACKAGE__,
35             },
36             }
37              
38             sub create_set_accessor {
39 0     0 1 0 my ($self, $caller_class, $property, $isa, $options) = @_;
40 0         0 my $property_key = $property;
41              
42 0         0 my $check_constraint = $isa->constraint();
43              
44             return subname "${caller_class}::set_$property" => sub {
45 0     0   0 my ($self, $value) = @_;
46              
47 0 0       0 if (! $check_constraint->($value)) {
48 0         0 confess sprintf($CONSTRAINT_CHECK_ERROR,
49             $property, $isa->type, $value
50             );
51             }
52            
53 0 0       0 if ($options->{'-optimized'}) {
54 0         0 $self->{$property_key} = $value;
55             }
56             else {
57 0         0 $self->__setattr__($property, $value);
58             }
59 0         0 return;
60             }
61 0         0 }
62              
63             sub create_mutator {
64 3     3 1 7 my ($self, $caller_class, $property, $isa, $options, $priv) = @_;
65 3         5 my $property_key = $property;
66              
67 3         22 my $check_constraint = $isa->constraint();
68              
69             return subname "${caller_class}::$property" => sub {
70 7     7   1971 my ($self, $value) = @_;
        7      
        7      
        7      
71              
72 7 100       25 if (defined $value) {
73 3 100       30 confess "Can't set value with $property(). It's read only!"
74             if not $priv->{has_setter};
75 2 50       11 if (! $check_constraint->($value)) {
76 0         0 confess sprintf($CONSTRAINT_CHECK_ERROR,
77             $property, $isa->type, $value
78             );
79             }
80 2 50       9 if ($options->{'-optimized'}) {
81 2         5 $self->{$property_key} = $value;
82             }
83             else {
84 0         0 $self->__setattr__($property, $value);
85             }
86 2         11 return;
87             }
88              
89 4 50       12 if (not $priv->{has_getter}) {
90 0         0 confess "Can only set value with $property(), it's write only!";
91             }
92              
93 4 100       12 if (!exists $self->{$property_key}) {
94            
95 2 50       8 if (_NEWSCHOOL_TYPE($isa)) {
    0          
96 2         9 $self->{$property_key} = $isa->default_value($self);
97             }
98             elsif (_OLDSCHOOL_TYPE($isa)) {
99 0         0 $self->{$property_key} = $isa->($self);
100             }
101             else {
102 0         0 $self->{$property_key} = $isa;
103             }
104             }
105              
106 4 50       24 return $options->{'-optimized'} ? $self->{$property_key}
107             : $self->__getattr__($property);
108             }
109 3         43 }
110             1;
111              
112             __END__