File Coverage

blib/lib/Class/Agreement.pm
Criterion Covered Total %
statement 252 270 93.3
branch 109 132 82.5
condition 17 29 58.6
subroutine 45 46 97.8
pod 6 6 100.0
total 429 483 88.8


line stmt bran cond sub pod time code
1             package Class::Agreement;
2              
3 19     19   706812 use warnings;
  19         48  
  19         649  
4 19     19   99 use strict;
  19         40  
  19         942  
5              
6             our $VERSION = '0.02';
7              
8 19     19   162 use Carp;
  19         37  
  19         2297  
9 19     19   20712 use Class::Inspector;
  19         85666  
  19         703  
10 19     19   639 use Scalar::Util qw(blessed);
  19         35  
  19         4211  
11              
12             =head1 NAME
13              
14             Class::Agreement - add contracts to your Perl classes easily
15              
16             =head1 SYNOPSIS
17              
18             package SomeClass;
19            
20             use Class::Agreement;
21            
22             # use base 'Class::Accessor' or 'Class::MethodMaker',
23             # or roll your own:
24             sub new { ... }
25              
26             invariant {
27             my ($self) = @_;
28             $self->count > 0;
29             };
30            
31             precondition add_a_positive => sub {
32             my ( $self, $value ) = @_;
33             return ( $value >= 0 );
34             };
35             sub add_a_positive {
36             my ( $self, $value ) = @_;
37             ...
38             }
39            
40             sub choose_word {
41             my ( $self, $value ) = @_;
42             ...
43             }
44             postcondition choose_word => sub {
45             return ( result >= 0 );
46             };
47            
48             dependent increase_foo => sub {
49             my ( $self, $amount ) = @_;
50             my $old_foo = $self->foo;
51             return sub {
52             my ( $self, $amount ) = @_;
53             return ( $old_foo < $self->get_foo );
54             }
55             };
56             sub increase_foo {
57             my ( $self, $amount ) = @_;
58             $self->set_foo( $self->get_foo + $amount );
59             }
60              
61             =head1 DESCRIPTION
62              
63             Class::Agreement is an implementation of behavioral contracts for Perl5. This
64             module allows you to easily add pre- and postconditions to new or existing Perl
65             classes.
66              
67             This module provides contracts such as dependent contracts, contracts for
68             higher-order functions, and informative messages when things fail. At the time
69             of this writing, Class::Agreement is one of only two contract implementations
70             that blames contract-breaking components correctly. (See: "Object-oriented
71             Programming Languages Need Well-founded Contracts" at
72             L.)
73              
74             Using Class::Agreement lets you specify proper input and output of your
75             functions or methods, thus strengthening your code and allowing you to spot
76             bugs earlier.
77              
78             =head2 Comparison with Class::Contract
79              
80             L requires you to use its own object and accessor system, which
81             makes the addition of contracts to existing code difficult. In contrast, it
82             should be easy to implement contracts with L no matter what
83             object system (C, L, L, etc.) you
84             use.
85              
86             L also clones objects every time you add a postcondition, which
87             can get pretty expensive. L doesn't clone -- alternatively, it
88             provides you with dependent contracts so that you can use closure to keep track
89             of only the values you care about. (See L.)
90              
91             =head2 Comparison with Eiffel
92              
93             You could say that L gives you Perl equivalents of Eiffel's
94             C, C, C and (indirectly) C keywords. For
95             example, the following Eiffel method:
96              
97             decrement is
98             require
99             item > 0
100             do
101             item := item - 1
102             ensure
103             item = old item - 1
104             end
105              
106             ...could be written in Perl as:
107              
108             use Class::Contract;
109             ...
110            
111             precondition decrement => sub { shift()->item > 0 }
112              
113             sub decrement {
114             my ( $self ) = @_;
115             $self->item( $self->item - 1 );
116             }
117              
118             dependent decrement => sub {
119             my ( $self ) = @_;
120             my $old_item = $self->item;
121             return sub { $self->item == $old_item - 1 };
122             };
123              
124             =head1 EXPORT
125              
126             The following functions are exported by default:
127              
128             =over 4
129              
130             =item * C, C, and C, each of which have two distinct calling syntaxes: one for functional programming and one for object-oriented.
131              
132             =item * C, which should only be used within postconditions or functions returned by dependent contracts.
133              
134             =item * C and C, both of which are used only in object-oriented programming.
135              
136             =back
137              
138             All exported functions are described in the following section, L.
139              
140             =cut
141              
142 19     19   112 use base 'Exporter';
  19         36  
  19         3787  
143              
144             our @EXPORT = qw(
145             result
146             precondition postcondition dependent invariant
147             specify_constructors
148             );
149              
150             my $contracts = {};
151              
152             my $constructors = {};
153              
154             #
155             # a separate subroutine is necessary to keep the exported function prototype
156             #
157             sub _real_result {
158 1     1   27 croak "function Class::Agreement::result() used outside of postcondition";
159             }
160              
161             sub result () {
162 101     101 1 474 goto &_real_result;
163             }
164              
165             sub _parent_class_of_method {
166              
167             # based off find_parent from SUPER.pm by Simon Cozens/chromatic
168 73     73   144 my ( $class, $method, $prune ) = @_;
169 73   50     374 $prune ||= '';
170             {
171 19     19   110 no strict 'refs';
  19         38  
  19         2473  
  73         102  
172 73         110 for my $parent ( @{ $class . '::ISA' }, 'UNIVERSAL' ) {
  73         300  
173 73 50       188 return _parent_class_of_method( $parent, $method )
174             if $parent eq $prune;
175 73 100       846 return $parent if $parent->can($method);
176             }
177             }
178             }
179              
180             sub _subroutine_exists {
181 219     219   380 my ($symbol) = @_;
182 19     19   121 no strict 'refs';
  19         61  
  19         3921  
183 219         259 *{$symbol}{CODE};
  219         1476  
184             }
185              
186             sub _check_arguments {
187 99     99   204 my ( $glob, $block ) = @_;
188 99         272 my $caller_name = [ caller(1) ]->[3];
189 99 50       2226 croak "first argument to $caller_name() was undefined"
190             unless defined $glob;
191 99 50       367 croak "second argument to $caller_name() was not a subroutine reference"
192             unless ref $block eq 'CODE';
193             }
194              
195             sub _add_contract_for_hierarchy {
196 84     84   202 my ( $package, $glob, $type, $inforef ) = @_;
197              
198             # if they're trying to add a contract to a method that isn't overridden,
199             # create a stub to attach the contract to
200 84         294 my $this_symbol = _package_and_method_to_symbol( $package, $glob );
201 84 100       248 if ( not _subroutine_exists($this_symbol) ) {
202 19     19   132 no strict 'refs';
  19         33  
  19         6228  
203 2 100       7 if ( my $parent = _parent_class_of_method( $package, $glob ) ) {
204 1         6 *{$this_symbol} = $parent->can($glob);
  1         7  
205             }
206             else {
207 1         11 croak
208             "can't add $type contract to undefined subroutine $this_symbol";
209             }
210             }
211              
212             my @classes
213 83 100       131 = ( $package, @{ Class::Inspector->subclasses($package) || [] } );
  83         437  
214 83         1265505 foreach my $source_class (@classes) {
215 135         553 my $symbol = _package_and_method_to_symbol( $source_class, $glob );
216 135 100       400 _add_contract( $symbol, $type, $inforef, $package )
217             if _subroutine_exists($symbol);
218             }
219             }
220              
221             sub _add_contract {
222 118     118   364 my ( $symbol, $type, $inforef, $source_class ) = @_;
223              
224             # if we already have a contract of this type...
225 118 100       388 if ( my @contracts = _get_contracts( $symbol, $type ) ) {
226              
227             # if this contract wasn't defined by our source class..
228 28 100       115 if ( $contracts[0]->[3] ne $source_class ) {
229              
230             # erase any existing contracts
231 13         71 _erase_contracts( $symbol, $type );
232             }
233             }
234              
235             # add our new contract
236 118         199 push @{ $contracts->{$symbol}{$type} }, [ @$inforef, $source_class ];
  118         660  
237              
238             # if the symbol doesn't have a wrapper, add one
239 118 100       578 if ( not _has_a_contract($symbol) ) {
240 71         311 _set_implementation( $symbol, \&$symbol );
241 19     19   338 no strict 'refs';
  19         36  
  19         573  
242 19     19   99 no warnings 'redefine';
  19         32  
  19         33222  
243 71         233 *{$symbol} = _make_method_wrapper($symbol);
  71         793  
244             }
245             }
246              
247             sub _set_implementation {
248 71     71   154 my ( $symbol, $block ) = @_;
249 71         212 $contracts->{$symbol}{impl} = $block;
250             }
251              
252             sub _get_implementation {
253 96     96   230 my ($symbol) = @_;
254 96         267 return $contracts->{$symbol}{impl};
255             }
256              
257             sub _has_a_contract {
258 118     118   277 my ($symbol) = @_;
259 118         823 return exists $contracts->{$symbol}{impl};
260             }
261              
262             sub _get_contracts {
263 815     815   1169 my ( $symbol, $type ) = @_;
264 815 100       853 @{ $contracts->{$symbol}{$type} || [] };
  815         5329  
265             }
266              
267             sub _erase_contracts {
268 140     140   217 my ( $symbol, $type ) = @_;
269 140         410 delete $contracts->{$symbol}{$type};
270             }
271              
272             sub _copy_of {
273 436     436   422 return @{ \@_ };
  436         1650  
274             }
275              
276             sub _symbol_to_package_and_method {
277 71     71   531 shift =~ /^(.+)::(.+)$/;
278             }
279              
280             sub _package_and_method_to_symbol {
281 318 100   318   1570 ( $_[1] =~ /::/ ) ? $_[1] : "$_[0]\::$_[1]";
282             }
283              
284             sub _is_constructor {
285 67     67   120 my ( $package, $name ) = @_;
286             return
287 67 100       264 exists $constructors->{$package}
288             ? exists $constructors->{$package}{$name}
289             : $name eq 'new';
290             }
291              
292             sub _set_constructors {
293 3     3   9 my ( $package, @constructors ) = @_;
294 3         9 my %lookup = ( map { ; $_ => 1 } @constructors );
  3         9  
295             $constructors->{$_} = \%lookup
296 3         13 for $package, Class::Inspector->subclasses($package);
297             }
298              
299             sub _get_constructors {
300 0     0   0 my ($package) = @_;
301 0   0     0 return $constructors->{$package} || [];
302             }
303              
304             sub _make_method_wrapper {
305 71     71   141 my ($symbol) = @_;
306 71         217 my ( $package, $method ) = _symbol_to_package_and_method($symbol);
307 71         244 my $parent = _parent_class_of_method( $package, $method );
308 71 50       267 my $parent_symbol =
309             defined $parent
310             ? _package_and_method_to_symbol( $parent, $method )
311             : undef;
312              
313             return sub {
314 128     128   112979 my @arguments = @_;
315              
316             #
317             # do invariants, blame outside sources
318             #
319 128 100       633 if ( blessed( $_[0] ) ) {
320 54         118 foreach ( _get_contracts( $symbol, 'invar' ) ) {
321 15         33 my ( $block, $file, $line ) = @$_;
322 15         22 my $success = eval { $block->( _copy_of( $arguments[0] ) ) };
  15         36  
323 15 50       1105 if ($@) {
    100          
324 0         0 croak "invariant for $symbol died: $@ "
325             . "from $file line $line";
326             }
327             elsif ( not $success ) {
328 1         17 croak "invariant for $symbol failed due to "
329             . "an outside source tampering with the object "
330             . "from $file line $line";
331             }
332             }
333             }
334              
335             #
336             # do dependent contracts
337             #
338 127         351 _erase_contracts( $symbol, 'temp-post' );
339 127         253 foreach ( _get_contracts( $symbol, 'dep' ) ) {
340 19         33 my ( $block, $file, $line ) = @$_;
341 19         28 my $postcondition = eval { $block->( _copy_of(@arguments) ) };
  19         47  
342 19 50       1156 if ($@) {
    100          
    50          
343 0         0 croak "dependent contract for $symbol died: $@ "
344             . "from $file line $line";
345             }
346             elsif ( not defined $postcondition ) {
347 3         13 return;
348             }
349             elsif ( ref $postcondition ne 'CODE' ) {
350 0         0 croak
351             "dependent contract for $symbol did not return either a "
352             . "subroutine reference or undefine at $file line $line";
353             }
354             else {
355 16         58 _add_contract( $symbol, 'temp-post',
356             [ $postcondition, $file, $line ], $package );
357             }
358             }
359              
360             #
361             # do preconditions
362             #
363 124         332 foreach ( _get_contracts( $symbol, 'pre' ) ) {
364 79         147 my ( $block, $file, $line ) = @$_;
365 79         100 my $success = eval { $block->( _copy_of(@arguments) ) };
  79         182  
366 79 50       1623 if ($@) {
    100          
367 0         0 croak "precondition for $symbol died: $@ "
368             . "from $file line $line";
369             }
370             elsif ( not $success ) {
371 28 100 66     127 if (defined $parent
372             and my @parent_contracts = _get_contracts(
373             _package_and_method_to_symbol( $parent, $method ),
374             'pre'
375             )
376             )
377             {
378 8         19 foreach (@parent_contracts) {
379 8         18 my ( $parent_block, $parent_file, $parent_line )
380             = @$_;
381 8 100       12 if ( eval { $parent_block->( _copy_of(@arguments) ) }
  8         19  
382             )
383             {
384 4         108 croak "precondition for $symbol failed "
385             . "from $parent_file line $parent_line (the parent) "
386             . "and file $file line $line (the child) -- "
387             . "check hierarchy between $parent and $package";
388             }
389             else {
390 4         90 croak "precondition for $symbol failed "
391             . "due to client input "
392             . "from file $file line $line";
393             }
394             }
395             }
396             else {
397 20         362 croak "precondition for $symbol failed "
398             . "from $file line $line";
399             }
400             }
401             }
402              
403             #
404             # we need to call the method/function in the same context in which the
405             # contract was called
406             #
407 96         278 my $implementation = _get_implementation($symbol);
408             my @result = ( not defined wantarray )
409 96 100       333 ? do { $implementation->( _copy_of(@arguments) ) }
  81 100       172  
410             : wantarray ? ( $implementation->( _copy_of(@arguments) ) )
411             : ( scalar $implementation->( _copy_of(@arguments) ) );
412              
413             #
414             # do postconditions
415             #
416             {
417 19     19   141 no strict 'refs';
  19         35  
  19         2203  
  96         1855  
418 19     19   117 no warnings 'redefine';
  19         206  
  19         30994  
419 96 100   74   493 local *_real_result = sub { wantarray ? @result : $result[0] };
  74         303  
420              
421 96         267 foreach (
422             _get_contracts( $symbol, 'post' ),
423             _get_contracts( $symbol, 'temp-post' )
424             )
425             {
426 66         120 my ( $child_block, $child_file, $child_line ) = @$_;
427              
428             my $child_success
429 66         87 = eval { $child_block->( _copy_of(@arguments) ) };
  66         205  
430 66 50 66     5370 if ($@) {
    100          
    100          
431 0         0 croak "postcondition for $symbol died: $@ "
432             . "from $child_file line $child_line";
433             }
434             elsif (
435             defined $parent
436             and my @parent_contracts = (
437             _get_contracts( $parent_symbol, 'post' ),
438             _get_contracts( $parent_symbol, 'temp-post' )
439             )
440             )
441             {
442 12         22 foreach (@parent_contracts) {
443 12         27 my ( $parent_block, $parent_file, $parent_line )
444             = @$_;
445             my $parent_success
446 12         19 = eval { $parent_block->( _copy_of(@arguments) ) };
  12         22  
447 12 50 100     153 if ($@) {
    100          
    100          
448 0         0 croak "postcondition for $symbol died: $@ "
449             . "from $child_file line $child_line";
450             }
451             elsif ( $child_success and not $parent_success ) {
452 2         58 croak "postcondition for $symbol failed "
453             . "at $parent_file line $parent_line (the parent) "
454             . "and file $child_file line $child_line (the child) -- "
455             . "check hierarchy between $parent and $package";
456             }
457             elsif ( not $child_success ) {
458 5         110 croak
459             "postcondition for $symbol failed since its "
460             . "implementation didn't adhere to the contract "
461             . "from file $child_file line $child_line";
462             }
463             }
464             }
465             elsif ( not $child_success ) {
466 22         1015 croak "postcondition for $symbol failed "
467             . "from $child_file line $child_line";
468             }
469             }
470             }
471              
472             #
473             # do invariants, blame method
474             #
475 67         225 my $is_constructor = _is_constructor( $package, $method );
476 67 100 100     452 if ( blessed( $_[0] ) or $is_constructor ) {
477 40         87 foreach ( _get_contracts( $symbol, 'invar' ) ) {
478 28         57 my ( $block, $file, $line ) = @$_;
479 28         41 my $success = eval {
480 28 100       73 $block->(
481             _copy_of(
482             $is_constructor ? $result[0] : $arguments[0]
483             )
484             );
485             };
486 28 50       2347 if ($@) {
    100          
487 0         0 croak "invariant for $symbol died: $@ "
488             . "from $file line $line";
489             }
490             elsif ( not $success ) {
491 1         33 croak "invariant for $symbol failed due to "
492             . "the method's implementation being broken "
493             . "from $file line $line";
494             }
495             }
496             }
497              
498 66 100       408 wantarray ? @result : $result[0];
499 71         2382 };
500             }
501              
502             =head1 FUNCTIONS
503              
504             =head2 precondition NAME, BLOCK
505              
506             Specify that the method NAME must meet the precondition as specified in BLOCK.
507              
508             In BLOCK, the variable C<@_> will be the argument list of the method. (The
509             first item of C<@_> will be the class name or object, as usual.)
510              
511             For example, to specify a precondition on a method to ensure that the first
512             argument given is greater than zero:
513              
514             precondition foo => sub {
515             my ( $self, $value ) = @_;
516             return ( $value >= 0 );
517             };
518             sub foo {
519             my ( $self, $value ) = @_;
520             ...
521             }
522              
523             With methods, if the precondition fails (returns false), preconditions for the
524             parent class will be checked. If the preconditions for both the child's method
525             and the parent's method fail, the input to the method must have been invalid. If
526             the precondition for the parent passes, the hierarchy between the class and the
527             parent class is incorrect because, to fulfill the Liskov-Wing principal of
528             substitutability, the subclass' method should accept that the superclass' does,
529             and optionally more. Note that only the relationships between child and parent
530             classes are checked -- this module won't traverse the complete ancestry of
531             a class.
532              
533             You can use this keyword multiple times to declare multiple preconditions on
534             the given method.
535              
536             =cut
537              
538             =head2 precondition VARIABLE, BLOCK
539              
540             Specify that, when called, the subroutine reference pointed to by the lvalue
541             VARIABLE must meet the precondition as specified in BLOCK.
542              
543             In BLOCK, the variable C<@_> will be the argument list of the subroutine.
544              
545             There are times when you will have a function or method that accepts another
546             function as an argument. Say that you have a function C that accepts
547             another function, C, as its argument. However, the argument given to C
548             must be greater than zero:
549              
550             sub g {
551             my ($f) = @_;
552             precondition $f => sub {
553             my ($value) = @_;
554             return ( $value >= 0 );
555             };
556             $f->(15); # will pass
557             $f->(-3); # will fail
558             }
559              
560             If called in void context this function will modify VARIABLE to point to a new
561             subroutine reference with the precondition. If called in scalar
562             context, this function will return a new function with the attached
563             precondition.
564              
565             You can use this keyword multiple times to declare multiple preconditions on
566             the given function.
567              
568             =cut
569              
570             sub precondition {
571 45     45 1 23743 my ( $glob, $block ) = @_;
572 45         193 my ( $package, $file, $line ) = caller();
573 45         1496 _check_arguments(@_);
574              
575 45 100 33     215 if ( not ref $glob ) {
    50          
576 29         124 _add_contract_for_hierarchy( $package, $glob,
577             pre => [ $block, $file, $line ] );
578             }
579              
580             elsif ( defined ref $glob and ref $glob eq 'CODE' ) {
581 16         40 my $original = $glob;
582             my $wrapped = sub {
583 20     20   4658 my @arguments = @_;
584 20         55 my $success = eval { $block->( _copy_of(@arguments) ) };
  20         45  
585 20 50       125 if ($@) {
    100          
586 0         0 croak "precondition for function died: $@";
587             }
588             elsif ( not $success ) {
589 7         102 croak
590             "precondition for function failed at $file line $line\n";
591             }
592 13         24 $original->( &_copy_of(@arguments) );
593 16         85 };
594 16 100       42 if ( defined wantarray ) {
595 1         4 return $wrapped;
596             }
597             else {
598 15         46 $_[0] = $wrapped;
599             }
600             }
601             else {
602 0         0 croak "first argument to precondition() "
603             . "was not a method name or code reference";
604             }
605             }
606              
607             =head2 postcondition NAME, BLOCK
608              
609             Specify that the method NAME must meet the postcondition as specified in BLOCK.
610              
611             In BLOCK, the variable C<@_> will be the argument list of the method. The
612             function C may be used to retrieve the return values of the method. If
613             the method returns a list, calling C in array context will return all
614             of return values, and calling C in scalar context will return only the
615             first item of that list. If the method returns a scalar, C called in
616             scalar context will be that scalar, and C in array context will return
617             a list with one element.
618              
619             For example, to specify a postcondition on a method to ensure that the method
620             returns a number less than zero, BLOCK would check the
621              
622             sub foo {
623             my ( $self, $value ) = @_;
624             ...
625             }
626             postcondition foo => sub {
627             return ( result >= 0 );
628             };
629              
630             With methods, postconditions for the parent class will be checked if they
631             exist. If the postcondition for the child's method fails, the blame lies with
632             the child method's implementation since it is not adhering to its contract. If
633             the postcondition for the child method passes, but the postcondition for the
634             parent's fails, the problem lies with the hierarchy betweeen the classes. Note
635             again that only the relationships between child and parent classes are checked
636             -- this module won't traverse the complete ancestry of a class.
637              
638             You can use this keyword multiple times to declare multiple postconditions on
639             the given method.
640              
641             =head2 postcondition VARIABLE, BLOCK
642              
643             Specify that, when called, the subroutine reference pointed to by the lvalue
644             VARIABLE must meet the postcondition as specified in BLOCK.
645              
646             In BLOCK, the varable C<@_> and function C are available and may be
647             used in the same ways as described in the previous usage of C.
648              
649             Say that you have a function C that accepts another function, C as its
650             argument. C, however, must return a number that is divisible by two. This
651             can be expressed as:
652              
653             sub g {
654             my ($f) = @_;
655             postcondition $f => sub {
656             return ! ( result % 2 );
657             };
658             ...
659             }
660              
661             If called in void context this function will modify VARIABLE to point to a new
662             subroutine reference with the postcondition. If called in scalar
663             context, this function will return a new function with the attached
664             postcondition.
665              
666             You can use this keyword multiple times to declare multiple postconditions on
667             the given function.
668              
669             =cut
670              
671             sub postcondition {
672 36     36 1 15162 my ( $glob, $block ) = @_;
673 36         173 my ( $package, $file, $line ) = caller();
674 36         985 _check_arguments(@_);
675              
676 36 100 33     405 if ( not ref $glob ) {
    50          
677 21         89 _add_contract_for_hierarchy( $package, $glob,
678             post => [ $block, $file, $line ] );
679             }
680              
681             elsif ( defined ref $glob and ref $glob eq 'CODE' ) {
682 15         24 my $implementation = $glob;
683             my $wrapped = sub {
684 21     21   4678 my @arguments = @_;
685              
686             my @result = ( not defined wantarray )
687 21 100       78 ? do { $implementation->( _copy_of(@arguments) ) }
  14 100       35  
688             : wantarray ? ( $implementation->( _copy_of(@arguments) ) )
689             : ( scalar $implementation->( _copy_of(@arguments) ) );
690              
691 19         886 my $success;
692             {
693 19     19   135 no strict 'refs';
  19         46  
  19         681  
  19         24  
694 19     19   93 no warnings 'redefine';
  19         35  
  19         11643  
695             local *_real_result
696 19 100       87 = sub { wantarray ? @result : $result[0] };
  28         163  
697              
698 19         29 $success = eval { $block->( _copy_of(@arguments) ) };
  19         37  
699              
700 19 50       7034 if ($@) {
    100          
701 0         0 croak "postcondition for function died: $@";
702             }
703             elsif ( not $success ) {
704 7         111 croak
705             "postcondition for function failed at $file line $line";
706             }
707             else {
708 12         43 goto &_real_result;
709             }
710             }
711 15         73 };
712 15 100       33 if ( defined wantarray ) {
713 3         12 return $wrapped;
714             }
715             else {
716 12         35 $_[0] = $wrapped;
717             }
718             }
719             else {
720 0         0 croak "first argument to precondition() "
721             . "was not a method name or code reference";
722             }
723             }
724              
725             =head2 dependent NAME, BLOCK
726              
727             Specify that the method NAME will use the subroutine reference returned by BLOCK
728             as a postcondition. If BLOCK returns undefined, no postcondition will be added.
729             In some cases, the postcondition returned will I on the input provided,
730             hence these are referred to as I. However, since the
731             arguments to the method are given in the postcondition, dependent contracts will
732             be used typically to compare old and new values.
733              
734             BLOCK is run at the same time as preconditions, thus the C<@_> variable works
735             in the same manner as in preconditions. However, the subroutine reference that
736             BLOCK returns will be invoked as a postcondition, thus it may the C
737             function in addition to C<@_>.
738              
739             You'll probably use these, along with closure, to check the old copies of
740             values. See the example in L.
741              
742             You can use this keyword multiple times to declare multiple dependent contracts
743             on the given method.
744              
745             =head2 dependent VARIABLE, BLOCK
746              
747             Specify that the subroutine reference pointed to by the lvalue VARIABLE will use
748             the subroutine reference returned by BLOCK as a postcondition. If BLOCK returns
749             undefined, no postcondition will be added.
750              
751             Identical to the previous usage, BLOCK is run at the same time as
752             preconditions, thus the C<@_> variable works in the same manner as in
753             preconditions. However, the subroutine reference that BLOCK returns will be
754             invoked as a postcondition, thus it may the C function in addition to
755             C<@_>.
756              
757             Say that you have a function C that accepts another function, C as its
758             argument. You want to make sure that C, as a side effect, adds to the
759             global variable C<$count>:
760              
761             my $count = 0;
762             ...
763              
764             sub g {
765             my ($f) = @_;
766             dependent $f => sub {
767             my $old_count = $count;
768             return sub { $count > $old_count };
769             };
770             ...
771             }
772              
773             You can use this keyword multiple times to declare multiple dependent contracts
774             on the given function.
775              
776             =cut
777              
778             sub dependent {
779 18     18 1 4948 my ( $glob, $block ) = @_;
780 18         67 my ( $package, $file, $line ) = caller();
781 18         484 _check_arguments(@_);
782              
783 18 100 33     81 if ( not ref $glob ) {
    50          
784 9         39 _add_contract_for_hierarchy( $package, $glob,
785             dep => [ $block, $file, $line ] );
786             }
787              
788             elsif ( defined ref $glob and ref $glob eq 'CODE' ) {
789 9         20 my $implementation = $glob;
790             my $wrapped = sub {
791 16     16   2531 my @arguments = @_;
792              
793 16         20 my $postcondition = eval { $block->( _copy_of(@arguments) ) };
  16         27  
794 16 50       692 if ($@) {
    100          
    50          
795 0         0 croak "dependent contract died: $@ " . "at $file line $line";
796             }
797             elsif ( not defined $postcondition ) {
798 3         20 return;
799             }
800             elsif ( ref $postcondition ne 'CODE' ) {
801 0         0 croak "dependent contract did not return either a "
802             . "subroutine reference or undefine from $file line $line";
803             }
804              
805             my @result = ( not defined wantarray )
806 13 50       30 ? do { $implementation->( _copy_of(@arguments) ) }
  9 100       13  
807             : wantarray ? ( $implementation->( _copy_of(@arguments) ) )
808             : ( scalar $implementation->( _copy_of(@arguments) ) );
809              
810 11         33 my $success;
811             {
812 19     19   111 no strict 'refs';
  19         37  
  19         815  
  11         11  
813 19     19   97 no warnings 'redefine';
  19         36  
  19         17302  
814             local *_real_result
815 11 100       33 = sub { wantarray ? @result : $result[0] };
  17         12690  
816 11         17 $success = eval { $postcondition->( _copy_of(@arguments) ) };
  11         18  
817              
818 11 50       1453 if ($@) {
    100          
819 0         0 croak "postcondition for function died: $@";
820             }
821             elsif ( not $success ) {
822 4         67 croak
823             "postcondition for function failed from $file line $line";
824             }
825             else {
826 7         38 goto &_real_result;
827             }
828             }
829 9         35 };
830 9 50       18 if ( defined wantarray ) {
831 0         0 return $wrapped;
832             }
833             else {
834 9         23 $_[0] = $wrapped;
835             }
836             }
837             else {
838 0         0 croak "first argument to precondition() "
839             . "was not a method name or code reference";
840             }
841             }
842              
843             =head2 invariant BLOCK
844              
845             BLOCK will be evaluated before and after every public method in the current
846             class. A I is described as any subroutine in the package whose
847             name begins with a letter and is not composed entirely of uppercase letters.
848              
849             Invariants will not be evaluated for class methods. More specifically,
850             invariants will only be evaluated when the first argument to a subroutine is
851             a blessed reference. This would mean that invariants would not be checked for
852             constructors, but C provides another function,
853             L<"specify_constructors">, which is used for this purpose. (See the following
854             section for details.)
855              
856             Invariant BLOCKS are provided with only one argument: the current object. An
857             exception is if the method is a constructor, the only argument to the BLOCK is
858             the first return value of the method. (If your constructors return an object as
859             the first or only return value -- as they normally do -- this means you're
860             fine.)
861              
862             Invariants are not checked when destructors are invoked. For an explanation as
863             to why, see L<"WHITEPAPER">.
864              
865             You can use this keyword multiple times to declare multiple invariant contracts
866             for the class.
867              
868             =head3 Blame
869              
870             Blaming violators of invariants is easy. If an invariant contract fails
871             following a method invocation, we assume that the check prior to the
872             invocation must have succeeded, so the implementation of the method is at
873             fault. If an invariant fails before the method runs, invariants must have
874             succeeded after the last method was called, so the object must have been
875             tampered with by an exogenous source. Eeek!
876              
877             =head3 Example
878              
879             For example, say that you have a class for Othello boards, which are typically
880             8x8 grids. Othello begins with four pieces already placed on the board and ends
881             when the board is full or there are no remaining moves. Thus, the board must
882             always have between four and sixty-four pieces, inclusive:
883              
884             invariant sub {
885             my ( $self ) = @_;
886             return ( $self->pieces >= 4 and $self->pieces <= 64 );
887             };
888              
889             If the invariant fails after a method is called, the method's implementation is
890             at fault. If the invariant fails before the method is run, an outside source has
891             tampered with the object.
892              
893             =cut
894              
895             sub invariant {
896 11     11 1 6806 my ($block) = @_;
897 11         60 my ( $package, $file, $line ) = caller();
898 11 50       380 croak "argument to invariant() was not a subroutine reference"
899             unless ref $block eq 'CODE';
900              
901 11         23 my %seen;
902             my @classes
903 11 100       18 = ( $package, @{ Class::Inspector->subclasses($package) || [] } );
  11         65  
904 11         142119 foreach my $class (@classes) {
905 91   100     907 my @methods =
      50        
906              
907             # ignore subs imported from Class::Agreement
908             grep {
909 105         190 0 + ( __PACKAGE__->can($_) || 0 )
910             != 0 + ( $class->can($_) || 0 )
911             }
912              
913             # skip methods we've already added contracts for
914 107         2397 grep { not $seen{$_}++ }
915              
916             # skip internal methods (DESTROY, etc.)
917 13 50       69 grep {/[a-z]/}
918              
919             # retrieve all non _* methods from $package
920 13         33 @{ Class::Inspector->methods( $class, 'public' ) || [] };
921              
922 13         44 foreach my $method (@methods) {
923 25         119 _add_contract_for_hierarchy( $class, $method,
924             invar => [ $block, $file, $line ] );
925             }
926             }
927             }
928              
929             =head2 specify_constructors LIST
930              
931             As described above, invariants are checked on public methods when the first
932             argument is an object. Since constructors are typically class methods (if not
933             also object methods), C needs to know which methods are
934             constructors so that it can check invariants against the constructors' return
935             values instead of simply ignoring them.
936              
937             By default, it is assumed that a method named C is the constructor. You
938             don't have to bother with this keyword if you don't specify any invariants or if
939             your only constructor is C.
940              
941             If your class has more constructors, you should specify all of them (including
942             C) with C so that invariants can be checked properly:
943              
944             package Othello::Board;
945             use Class::Agreement;
946              
947             specify_constructors qw( new new_random );
948              
949             invariant sub {
950             my ( $self ) = @_;
951             return ( $self->pieces >= 4 and $self->pieces <= 64 );
952             };
953              
954             sub new {
955             ...
956             return bless [], shift;
957             }
958              
959             sub new_random {
960             ...
961             return bless [], shift;
962             }
963              
964             Any subclasses of C would also have the invariants of the
965             methods C and C checked as constructors. You can override
966             the specified constructors of any class -- all subclasses will use the settings
967             specified by their parents.
968              
969             If, for some reason, your class has no constructors, you can pass
970             C an empty list:
971              
972             specify_constructors ();
973              
974             =cut
975              
976             sub specify_constructors {
977 3     3 1 16 my (@constructors) = @_;
978 3         15 my ( $package, $file, $line ) = caller();
979 3         98 _set_constructors( $package, @constructors );
980             }
981              
982             =head1 REAL-LIFE EXAMPLES
983              
984             =head2 Checking a method's input
985              
986             Say that you have a board game that uses a graph of tiles. Every turn, players
987             draw a tile and, if it's placable, plop it into the graph. The method
988             C of the C class should take a placable tile as an
989             argument, which we can express as a contract:
990              
991             precondition insert_tile => sub {
992             my ( $self, $tile ) = @_;
993             return $self->verify_tile_fits( $tile );
994             };
995              
996             sub insert_tile {
997             my ( $self, $tile ) = @_;
998             ...
999             }
1000              
1001             Before the implementation of C is executed, the precondition
1002             checks to ensure that C<$tile> is placable in the graph as determined by
1003             C.
1004              
1005             =head2 Checking a method's output
1006              
1007             Using the C class from the previous example, say we have a method
1008             C which, given an C and C, will return all tiles
1009             surrounding the tile at that position. If the tiles are square, any given tile
1010             shouldn't have more than eight neighbors:
1011              
1012             sub get_neighbors {
1013             my ( $self, $x, $y ) = @_;
1014             ...
1015             }
1016              
1017             postcondition get_neighbors => sub {
1018             return ( (result) <= 8 );
1019             };
1020              
1021             The postcondition ensures that C returns no more than eight
1022             items.
1023              
1024             =head2 Testing old values
1025              
1026             Dependent contracts occur when the postcondition I on the input given
1027             to the method. You can use dependent contracts to save old copies of values
1028             through the use of closure.
1029              
1030             Given the C class from previous examples, say that the tiles in the
1031             graph are stored in a list. If insert tile has successfully added the tile to
1032             the graph, the number of tiles in the graph should have increased by one. Using
1033             the C function, we return a closure that will check exactly this:
1034              
1035             dependent insert_tile => sub {
1036             my ( $self, $tile ) = @_;
1037             my $old_count = $self->num_tiles;
1038             return sub {
1039             my ( $self, $tile ) = @_;
1040             return ( $self->num_tiles > $old_count );
1041             };
1042             };
1043              
1044             sub insert_tile {
1045             my ( $self, $tile ) = @_;
1046             ...
1047             }
1048              
1049             Before the implementation of C is run, the block given to
1050             C is run, which returns a closure. This closure is then run after
1051             C as if it were a precondition. (Thus, the closure returned by
1052             the block may make use the C function as well as C<@_>.)
1053              
1054             =head2 Contracts on coderefs
1055              
1056             This is where contracts get interesting. Say that you have a function C
1057             that takes a function C as an argument and returns a number greater than
1058             zero. However, C has a contract, too: it must take a natural number as the
1059             first argument and must return a single letter of the alphabet. This can be
1060             represented as follows:
1061              
1062             precondition g => sub {
1063             # first argument of @_ is f()
1064             precondition $_[0] => sub {
1065             my ( $val ) = @_;
1066             return ( $val =~ /^\d+$/ );
1067             };
1068             postcondition $_[0] => sub {
1069             return ( result =~ /^[A-Z]$/i );
1070             };
1071             };
1072              
1073             sub g {
1074             my ($f) = @_;
1075             ... # call $f somehow
1076             }
1077              
1078             postcondition g => sub {
1079             return ( result > 0 );
1080             };
1081              
1082             Thus, when the function C is used within C, the contracts set up for
1083             C in the precondition apply to it.
1084              
1085             =head1 FAQ
1086              
1087             =head2 Aren't contracts just assertions I could write with something like C ?
1088              
1089             The answer to this has been nicely worded by Jim Weirich in "Design by Contract
1090             and Unit Testing" located at
1091             L:
1092              
1093             "Although Design by Contract and assertions are very closely related, DbC is
1094             more than just slapping a few assertions into your code at strategic locations.
1095             It is about identifying the contract under which your code will execute and you
1096             expect all clients to adhere to. It is about clearly defining responsibilities
1097             between client software and supplier software.
1098              
1099             "In short, Design by Contract starts by specifying the conditions under which
1100             it is legal to call a method. It is the responsibility of the client software
1101             to ensure these conditions (called preconditions) are met.
1102              
1103             "Given that the preconditions are met, the method in the supplier software
1104             guarantees that certion other conditions will be true when the method returns.
1105             These are called postcondition, and are the responsibility of the supplier code
1106             in ensure."
1107              
1108             =head2 Why not just use Carp::Assert?
1109              
1110             Use L and L if you need to check I. If you
1111             want to assert I, L does everything that
1112             L can do for you B it determines which components are faulty
1113             when something fails.
1114              
1115             If you're looking for the sexiness of L, try using
1116             L with something like L:
1117              
1118             use Class::Agreement;
1119             use Data::Validate qw(:math :string);
1120              
1121             precondition foo => sub { is_integer( $_[1] ) };
1122             precondition bar => sub { is_greater_than( $_[1], 0 ) };
1123             precondition baz => sub { is_alphanumeric( $_[1] ) };
1124              
1125             =head2 How do I save an old copy of the object?
1126              
1127             Hopefully you don't need to. Just save the variable (or variables) you need to
1128             check in the postcondition by creating closures. See L
1129             for an example of how to do this.
1130              
1131             =head2 How do I disable contracts?
1132              
1133             Before you ask this, B. If your contracts
1134             are slowing down your program, first try following these guidelines:
1135              
1136             =over 4
1137              
1138             =item * B
1139              
1140             Cloning in Perl is expensive. Hopefully you've read the above examples on
1141             L and have realized that cloning an object isn't
1142             necessary.
1143              
1144             =item * B
1145              
1146             If your contract is performing the exact same tasks or calculations that are in
1147             the function itself, toss it. Only code the essentials into the contracts, such
1148             as "this function returns a number greater than twelve" or "the object was
1149             modified in this mannar."
1150              
1151             =item * B
1152              
1153             You can if you want, but contracts are designed to be I
1154             behavior>, not to enforce the types of data structures you're passing around.
1155              
1156             =back
1157              
1158             If you really want to disable this module, replace C with
1159             C, which exports identically-named functions that
1160             do nothing.
1161              
1162             =head2 What do you mean, "There's a problem with the hierarchy?"
1163              
1164             The Liskov-Wing principle states, "The objects of subtype ought to behave the
1165             same as those of the supertype as far as anyone or any program using the
1166             supertype objects can tell." (See: "Liskov Wing Subtyping" at
1167             L.) Say that C is a parent
1168             class of C, and both classes implement a method C, and both
1169             implementations have pre- and postconditions. According to Liskov-Wing, the
1170             valid input of C should be a I of the valid input of
1171             C. Thus, if the precondition for C fails but the
1172             precondition for C passes, the class heiarchy fails the principle.
1173             Postconditions are the opposite: the output of C should be
1174             a I of the output of C. If the postcondition for
1175             C passes but the postcondition for C fails, this
1176             violates the principle.
1177              
1178             =head2 Can I modify the argument list?
1179              
1180             If the argument list C<@_> is made up of simple scalars, no. However, if the
1181             method or function is passed a reference of some sort. This is a Bad Thing
1182             because your code should
1183              
1184             =head2 How can I type less?
1185              
1186             ...or more ugly? Use implicit returns and don't name your variables. For
1187             example, the dependent contract in L could be written as
1188             follows:
1189              
1190             dependent insert_tile => sub {
1191             my $o = shift()->num_tiles;
1192             sub { shift()->num_tiles > $o };
1193             };
1194              
1195             Other examples:
1196              
1197             precondition sqrt => sub { shift() > 0 };
1198              
1199             postcondition digits => sub { result =~ /^\d+$/ };
1200              
1201             invariant sub { shift()->size > 4 };
1202              
1203             Or, write your own generator to make things clean:
1204              
1205             sub argument_is_divisible_by {
1206             my $num = shift;
1207             return sub { not $_[1] % $num };
1208             }
1209              
1210             precondition foo => argument_is_divisible_by(2);
1211             precondition bar => argument_is_divisible_by(3);
1212              
1213             =head2 What if I generate methods?
1214              
1215             There's no problem as long as you build your subroutines before runtime,
1216             probably by sticking the generation in a C block.
1217              
1218             Here's a snippet from one of the included tests, F. Three
1219             methods, C, C and C, are created and given an assertion that the
1220             argument passed to them must be greater than zero:
1221              
1222             my $assertion = sub { $_[1] > 0 };
1223             precondition foo => $assertion;
1224             precondition bar => $assertion;
1225             precondition baz => $assertion;
1226              
1227             BEGIN {
1228             no strict 'refs';
1229             *{$_} = sub { }
1230             for qw( foo bar baz );
1231             }
1232              
1233             =head1 CAVEATS
1234              
1235             =over 4
1236              
1237             =item * You can't add contracts for abstract methods. If you try to add a contract to a method that isn't implemented in the given class or any of its parents, L will croak. One must declare an empty subroutine to get around this.
1238              
1239             =item * The C keyword will not properly report void context to any methods with contracts.
1240              
1241             =item * The C keyword will return an extra stack frame.
1242              
1243             =back
1244              
1245             =head1 AUTHOR
1246              
1247             Ian Langworth, C<< >>
1248              
1249             =head1 BUGS
1250              
1251             Please report any bugs or feature requests to
1252             C, or through the web interface at
1253             L.
1254             I will be notified, and then you'll automatically be notified of progress on
1255             your bug as I make changes.
1256              
1257             =head1 ACKNOWLEDGEMENTS
1258              
1259             Thanks to Prof. Matthias Felleisen who granted me a directed study to pursue
1260             this project and guided me during its development.
1261              
1262             Thanks to a number of other people who contributed to this module in some way,
1263             including: Damian Conway, Simon Cozens, Dan "Lamech" Friedman, Uri Guttman,
1264             Christian Hansen, Adrian Howard, David Landgren, Curtis "Ovid" Poe, Ricardo
1265             SIGNES, Richard Soderburg, Jesse Vincent.
1266              
1267             =head1 SEE ALSO
1268              
1269             L, L, L, L,
1270             L
1271              
1272             L,
1273             L
1274              
1275             =head1 COPYRIGHT & LICENSE
1276              
1277             Copyright 2005 Ian Langworth, All Rights Reserved.
1278              
1279             This program is free software; you can redistribute it and/or modify it
1280             under the same terms as Perl itself.
1281              
1282             =cut
1283              
1284             1; # End of Class::Agreement
1285