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.60';
7 34     34   237 use strict;
  34         73  
  34         995  
8 34     34   173 use warnings;
  34         71  
  34         1062  
9              
10 34     34   18322 use Params::Validate qw(validate_pos);
  34         309298  
  34         3914  
11              
12             sub import
13             {
14 287     287   6257 my $caller = caller;
15 287         492 shift; # don't need class name
16 287         1247 my %p = @_;
17              
18 287 100       1047 if ($p{read_only})
19             {
20 249 50       972 foreach my $ro ( ref $p{read_only} ? @{ $p{read_only} } : $p{read_only} )
  249         943  
21             {
22 34     34   266 no strict 'refs';
  34         70  
  34         6490  
23 1990     55947   8006 *{"$caller\::$ro"} = sub { return $_[0]->{$ro} };
  1990         11729  
  55947         189879  
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       1059 if ($p{read_write})
34             {
35 134 50       576 foreach my $rw ( ref $p{read_write} ? @{ $p{read_write} } : $p{read_write} )
  134         373  
36             {
37 450 100       1102 if (ref $rw)
38             {
39 410         923 my ($name, $spec) = @$rw;
40             my $sub =
41 5137 100   5137   11088 sub { if (@_ > 1)
42             {
43 58         138 my $s = shift;
44 58         1033 validate_pos(@_, $spec);
45 57         227 $s->{$name} = shift;
46 57         180 return $s->{$name};
47             }
48 5079         18051 return $_[0]->{$name};
49 410         1976 };
50 34     34   261 no strict 'refs';
  34         75  
  34         4196  
51 410         669 *{"$caller\::$name"} = $sub
  410         2292  
52             }
53             else
54             {
55             my $sub =
56 289 100   289   856 sub { if (@_ > 1)
57             {
58 217         665 $_[0]->{$rw} = $_[1];
59             }
60 289         821 return $_[0]->{$rw};
61 40         195 };
62 34     34   270 no strict 'refs';
  34         94  
  34         6794  
63 40         79 *{"$caller\::$rw"} = $sub;
  40         716  
64             }
65             }
66             }
67              
68 287 100       422531 if ($p{read_write_contained})
69             {
70 32         264 foreach my $object (keys %{ $p{read_write_contained} })
  32         267  
71             {
72 32         138 foreach my $rwc (@{ $p{read_write_contained}{$object} })
  32         179  
73             {
74 288 50       869 if (ref $rwc)
75             {
76 288         677 my ($name, $spec) = @$rwc;
77             my $sub =
78 391     391   694 sub { my $s = shift;
79 391         649 my %new;
80 391 50       939 if (@_)
81             {
82 391         4818 validate_pos(@_, $spec);
83 390         1494 %new = ( $name => $_[0] );
84             }
85 390         2157 my %args = $s->delayed_object_params( $object,
86             %new );
87 390         9319 return $args{$rwc};
88 288         1658 };
89 34     34   274 no strict 'refs';
  34         88  
  34         5162  
90 288         601 *{"$caller\::$name"} = $sub;
  288         102531  
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   266 no strict 'refs';
  34         85  
  34         4567  
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