home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / MethodMaker.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-12  |  4.6 KB  |  171 lines

  1. # Copyright (c) 1998-2003 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.  
  7. use strict;
  8.  
  9. use Params::Validate qw(validate_pos);
  10.  
  11. sub import
  12. {
  13.     my $caller = caller;
  14.     shift; # don't need class name
  15.     my %p = @_;
  16.  
  17.     if ($p{read_only})
  18.     {
  19.     foreach my $ro ( ref $p{read_only} ? @{ $p{read_only} } : $p{read_only} )
  20.     {
  21.         no strict 'refs';
  22.         *{"$caller\::$ro"} = sub { return $_[0]->{$ro} };
  23.     }
  24.     }
  25.  
  26.     #
  27.     # The slight weirdness to avoid calling shift in these rw subs is
  28.     # _intentional_.  These subs get called a lot simply to read the
  29.     # value, and optimizing this common case actually does achieve
  30.     # something.
  31.     #
  32.     if ($p{read_write})
  33.     {
  34.     foreach my $rw ( ref $p{read_write} ? @{ $p{read_write} } : $p{read_write} )
  35.     {
  36.         if (ref $rw)
  37.         {
  38.         my ($name, $spec) = @$rw;
  39.         no strict 'refs';
  40.         *{"$caller\::$name"} =
  41.             sub { if (@_ > 1)
  42.               {
  43.                               my $s = shift;
  44.                   validate_pos(@_, $spec);
  45.                   $s->{$name} = shift;
  46.                               return $s->{$name};
  47.               }
  48.               return $_[0]->{$name};
  49.                 };
  50.         }
  51.         else
  52.         {
  53.         no strict 'refs';
  54.         *{"$caller\::$rw"} =
  55.                     sub { if (@_ > 1)
  56.                           {
  57.                               $_[0]->{$rw} = $_[1];
  58.                           }
  59.                           return $_[0]->{$rw};
  60.                         };
  61.         }
  62.     }
  63.     }
  64.  
  65.     if ($p{read_write_contained})
  66.     {
  67.     foreach my $object (keys %{ $p{read_write_contained} })
  68.     {
  69.         foreach my $rwc (@{ $p{read_write_contained}{$object} })
  70.         {
  71.         if (ref $rwc)
  72.         {
  73.             my ($name, $spec) = @$rwc;
  74.             no strict 'refs';
  75.             *{"$caller\::$name"} =
  76.             sub { my $s = shift;
  77.                   my %new;
  78.                   if (@_)
  79.                   {
  80.                   validate_pos(@_, $spec);
  81.                   %new = ( $name => $_[0] );
  82.                   }
  83.                   my %args = $s->delayed_object_params( $object,
  84.                                     %new );
  85.                   return $args{$rwc};
  86.               };
  87.         }
  88.         else
  89.         {
  90.             no strict 'refs';
  91.             *{"$caller\::$rwc"} = sub { my $s = shift;
  92.                         my %new = @_ ? ( $rwc => $_[0] ) : ();
  93.                         my %args = $s->delayed_object_params( $object,
  94.                                               %new );
  95.                         return $args{$rwc};
  96.                         };
  97.         }
  98.         }
  99.     }
  100.     }
  101. }
  102.  
  103. 1;
  104.  
  105. =pod
  106.  
  107. =head1 NAME
  108.  
  109. HTML::Mason::MethodMaker - Used to create simple get & get/set methods in other classes
  110.  
  111. =head1 SYNOPSIS
  112.  
  113.  use HTML::Mason::MethodMaker
  114.      ( read_only => 'foo',
  115.        read_write => [
  116.                       [ bar => { type => SCALAR } ],
  117.                       [ baz => { isa => 'HTML::Mason::Baz' } ],
  118.                       'quux', # no validation
  119.                      ],
  120.        read_write_contained => { other_object =>
  121.                                  [
  122.                                   [ 'thing1' => { isa => 'Thing1' } ],
  123.                                   'thing2', # no validation
  124.                                  ]
  125.                                },
  126.      );
  127.  
  128. =head1 DESCRIPTION
  129.  
  130. This automates the creation of simple accessor methods.
  131.  
  132. =head1 USAGE
  133.  
  134. This module creates methods when it is C<use>'d by another module.
  135. There are three types of methods: 'read_only', 'read_write',
  136. 'read_write_contained'.
  137.  
  138. Attributes specified as 'read_only' get an accessor that only returns
  139. the value of the attribute.  Presumably, these attributes are set via
  140. more complicated methods in the class or as a side effect of one of
  141. its methods.
  142.  
  143. Attributes specified as 'read_write' will take a single optional
  144. parameter.  If given, this parameter will become the new value of the
  145. attribute.  This value is then returned from the method.  If no
  146. parameter is given, then the current value is returned.
  147.  
  148. If you want the accessor to use C<Params::Validate> to validate any
  149. values passed to the accessor (and you _do_), then the the accessor
  150. specification should be an array reference containing two elements.
  151. The first element is the accessor name and the second is the
  152. validation spec.
  153.  
  154. The 'read_write_contained' parameter is used to create accessor for
  155. delayed contained objects.  A I<delayed> contained object is one that
  156. is B<not> created in the containing object's accessor, but rather at
  157. some point after the containing object is constructed.  For example,
  158. the Interpreter object creates Request objects after the Interpreter
  159. itself has been created.
  160.  
  161. The value of the 'read_write_contained' parameter should be a hash
  162. reference.  The keys are the internal name of the contained object,
  163. such as "request" or "buffer".  The values for the keys are the same
  164. as the parameters given for 'read_write' accessors.
  165.  
  166. =head1 SEE ALSO
  167.  
  168. L<HTML::Mason|HTML::Mason>
  169.  
  170. =cut
  171.