File Coverage

blib/lib/HTML/Mason/MethodMaker.pm
Criterion Covered Total %
statement 70 77 90.9
branch 16 22 72.7
condition n/a
subroutine 13 14 92.8
pod n/a
total 99 113 87.6


line stmt bran cond sub pod time code
1             # Copyright (c) 1998-2005 by Jonathan Swartz. All rights reserved.
2             # This program is free software; you can redistribute it and/or modify it
3             # under the same terms as Perl itself.
4              
5             package HTML::Mason::MethodMaker;
6             $HTML::Mason::MethodMaker::VERSION = '1.59';
7 34     34   227 use strict;
  34         107  
  34         977  
8 34     34   170 use warnings;
  34         56  
  34         1018  
9              
10 34     34   18077 use Params::Validate qw(validate_pos);
  34         306432  
  34         4412  
11              
12             sub import
13             {
14 287     287   6387 my $caller = caller;
15 287         518 shift; # don't need class name
16 287         1356 my %p = @_;
17              
18 287 100       1015 if ($p{read_only})
19             {
20 249 50       1014 foreach my $ro ( ref $p{read_only} ? @{ $p{read_only} } : $p{read_only} )
  249         893  
21             {
22 34     34   263 no strict 'refs';
  34         69  
  34         6237  
23 1990     55947   8003 *{"$caller\::$ro"} = sub { return $_[0]->{$ro} };
  1990         11374  
  55947         184240  
24             }
25             }
26              
27             #
28             # The slight weirdness to avoid calling shift in these rw subs is
29             # _intentional_. These subs get called a lot simply to read the
30             # value, and optimizing this common case actually does achieve
31             # something.
32             #
33 287 100       1003 if ($p{read_write})
34             {
35 134 50       543 foreach my $rw ( ref $p{read_write} ? @{ $p{read_write} } : $p{read_write} )
  134         381  
36             {
37 450 100       1211 if (ref $rw)
38             {
39 410         905 my ($name, $spec) = @$rw;
40             my $sub =
41 5137 100   5137   10566 sub { if (@_ > 1)
42             {
43 58         98 my $s = shift;
44 58         990 validate_pos(@_, $spec);
45 57         215 $s->{$name} = shift;
46 57         162 return $s->{$name};
47             }
48 5079         16825 return $_[0]->{$name};
49 410         2201 };
50 34     34   263 no strict 'refs';
  34         75  
  34         4299  
51 410         696 *{"$caller\::$name"} = $sub
  410         2354  
52             }
53             else
54             {
55             my $sub =
56 289 100   289   887 sub { if (@_ > 1)
57             {
58 217         707 $_[0]->{$rw} = $_[1];
59             }
60 289         771 return $_[0]->{$rw};
61 40         191 };
62 34     34   257 no strict 'refs';
  34         140  
  34         6658  
63 40         79 *{"$caller\::$rw"} = $sub;
  40         733  
64             }
65             }
66             }
67              
68 287 100       416726 if ($p{read_write_contained})
69             {
70 32         332 foreach my $object (keys %{ $p{read_write_contained} })
  32         233  
71             {
72 32         159 foreach my $rwc (@{ $p{read_write_contained}{$object} })
  32         177  
73             {
74 288 50       984 if (ref $rwc)
75             {
76 288         748 my ($name, $spec) = @$rwc;
77             my $sub =
78 391     391   645 sub { my $s = shift;
79 391         594 my %new;
80 391 50       978 if (@_)
81             {
82 391         4735 validate_pos(@_, $spec);
83 390         1522 %new = ( $name => $_[0] );
84             }
85 390         2098 my %args = $s->delayed_object_params( $object,
86             %new );
87 390         8673 return $args{$rwc};
88 288         1910 };
89 34     34   303 no strict 'refs';
  34         95  
  34         5462  
90 288         558 *{"$caller\::$name"} = $sub;
  288         100253  
91             }
92             else
93             {
94             my $sub =
95 0     0     sub { my $s = shift;
96 0 0         my %new = @_ ? ( $rwc => $_[0] ) : ();
97 0           my %args = $s->delayed_object_params( $object,
98             %new );
99 0           return $args{$rwc};
100 0           };
101 34     34   281 no strict 'refs';
  34         85  
  34         4085  
102 0           *{"$caller\::$rwc"} = $sub;
  0            
103             }
104             }
105             }
106             }
107             }
108              
109             1;
110              
111             =pod
112              
113             =head1 NAME
114              
115             HTML::Mason::MethodMaker - Used to create simple get & get/set methods in other classes
116              
117             =head1 SYNOPSIS
118              
119             use HTML::Mason::MethodMaker
120             ( read_only => 'foo',
121             read_write => [
122             [ bar => { type => SCALAR } ],
123             [ baz => { isa => 'HTML::Mason::Baz' } ],
124             'quux', # no validation
125             ],
126             read_write_contained => { other_object =>
127             [
128             [ 'thing1' => { isa => 'Thing1' } ],
129             'thing2', # no validation
130             ]
131             },
132             );
133              
134             =head1 DESCRIPTION
135              
136             This automates the creation of simple accessor methods.
137              
138             =head1 USAGE
139              
140             This module creates methods when it is C'd by another module.
141             There are three types of methods: 'read_only', 'read_write',
142             'read_write_contained'.
143              
144             Attributes specified as 'read_only' get an accessor that only returns
145             the value of the attribute. Presumably, these attributes are set via
146             more complicated methods in the class or as a side effect of one of
147             its methods.
148              
149             Attributes specified as 'read_write' will take a single optional
150             parameter. If given, this parameter will become the new value of the
151             attribute. This value is then returned from the method. If no
152             parameter is given, then the current value is returned.
153              
154             If you want the accessor to use C to validate any
155             values passed to the accessor (and you _do_), then the the accessor
156             specification should be an array reference containing two elements.
157             The first element is the accessor name and the second is the
158             validation spec.
159              
160             The 'read_write_contained' parameter is used to create accessor for
161             delayed contained objects. A I contained object is one that
162             is B created in the containing object's accessor, but rather at
163             some point after the containing object is constructed. For example,
164             the Interpreter object creates Request objects after the Interpreter
165             itself has been created.
166              
167             The value of the 'read_write_contained' parameter should be a hash
168             reference. The keys are the internal name of the contained object,
169             such as "request" or "compiler". The values for the keys are the same
170             as the parameters given for 'read_write' accessors.
171              
172             =cut