diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-07-31 21:15:26 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-07-31 21:15:26 -0700 |
commit | ed7422811df45bc27a3ad79b1478ba6440c189ba (patch) | |
tree | 5f6f31564450946bab065a641db1f7efc3f6508d /dist | |
parent | 2cd46bfd6d03cd8826c5e968efdd36416191bc8f (diff) | |
download | perl-ed7422811df45bc27a3ad79b1478ba6440c189ba.tar.gz |
Attribute::Handlers: re-indent verbatim pod
This commit re-indents the code examples in Attribute::Handlers
to make things more consistent overall and to prevent long lines
from wrapping in 80-column terminals.
Diffstat (limited to 'dist')
-rw-r--r-- | dist/Attribute-Handlers/lib/Attribute/Handlers.pm | 493 |
1 files changed, 248 insertions, 245 deletions
diff --git a/dist/Attribute-Handlers/lib/Attribute/Handlers.pm b/dist/Attribute-Handlers/lib/Attribute/Handlers.pm index 4333155a80..60b61ac1d3 100644 --- a/dist/Attribute-Handlers/lib/Attribute/Handlers.pm +++ b/dist/Attribute-Handlers/lib/Attribute/Handlers.pm @@ -4,7 +4,7 @@ use Carp; use warnings; use strict; use vars qw($VERSION $AUTOLOAD); -$VERSION = '0.91'; # remember to update version in POD! +$VERSION = '0.92'; # remember to update version in POD! # $DB::single=1; my %symcache; @@ -266,68 +266,68 @@ Attribute::Handlers - Simpler definition of attribute handlers =head1 VERSION -This document describes version 0.91 of Attribute::Handlers, -released May 20, 2011. +This document describes version 0.92 of Attribute::Handlers, +released August 20, 2011. =head1 SYNOPSIS - package MyClass; - require 5.006; - use Attribute::Handlers; - no warnings 'redefine'; + package MyClass; + require 5.006; + use Attribute::Handlers; + no warnings 'redefine'; - sub Good : ATTR(SCALAR) { - my ($package, $symbol, $referent, $attr, $data) = @_; + sub Good : ATTR(SCALAR) { + my ($package, $symbol, $referent, $attr, $data) = @_; - # Invoked for any scalar variable with a :Good attribute, - # provided the variable was declared in MyClass (or - # a derived class) or typed to MyClass. + # Invoked for any scalar variable with a :Good attribute, + # provided the variable was declared in MyClass (or + # a derived class) or typed to MyClass. - # Do whatever to $referent here (executed in CHECK phase). - ... - } + # Do whatever to $referent here (executed in CHECK phase). + ... + } - sub Bad : ATTR(SCALAR) { - # Invoked for any scalar variable with a :Bad attribute, - # provided the variable was declared in MyClass (or - # a derived class) or typed to MyClass. - ... - } + sub Bad : ATTR(SCALAR) { + # Invoked for any scalar variable with a :Bad attribute, + # provided the variable was declared in MyClass (or + # a derived class) or typed to MyClass. + ... + } - sub Good : ATTR(ARRAY) { - # Invoked for any array variable with a :Good attribute, - # provided the variable was declared in MyClass (or - # a derived class) or typed to MyClass. - ... - } + sub Good : ATTR(ARRAY) { + # Invoked for any array variable with a :Good attribute, + # provided the variable was declared in MyClass (or + # a derived class) or typed to MyClass. + ... + } - sub Good : ATTR(HASH) { - # Invoked for any hash variable with a :Good attribute, - # provided the variable was declared in MyClass (or - # a derived class) or typed to MyClass. - ... - } + sub Good : ATTR(HASH) { + # Invoked for any hash variable with a :Good attribute, + # provided the variable was declared in MyClass (or + # a derived class) or typed to MyClass. + ... + } - sub Ugly : ATTR(CODE) { - # Invoked for any subroutine declared in MyClass (or a - # derived class) with an :Ugly attribute. - ... - } + sub Ugly : ATTR(CODE) { + # Invoked for any subroutine declared in MyClass (or a + # derived class) with an :Ugly attribute. + ... + } - sub Omni : ATTR { - # Invoked for any scalar, array, hash, or subroutine - # with an :Omni attribute, provided the variable or - # subroutine was declared in MyClass (or a derived class) - # or the variable was typed to MyClass. - # Use ref($_[2]) to determine what kind of referent it was. - ... - } + sub Omni : ATTR { + # Invoked for any scalar, array, hash, or subroutine + # with an :Omni attribute, provided the variable or + # subroutine was declared in MyClass (or a derived class) + # or the variable was typed to MyClass. + # Use ref($_[2]) to determine what kind of referent it was. + ... + } - use Attribute::Handlers autotie => { Cycle => Tie::Cycle }; + use Attribute::Handlers autotie => { Cycle => Tie::Cycle }; - my $next : Cycle(['A'..'Z']); + my $next : Cycle(['A'..'Z']); =head1 DESCRIPTION @@ -349,7 +349,8 @@ attribute C<:ATTR>. For example: use Attribute::Handlers; sub Loud :ATTR { - my ($package, $symbol, $referent, $attr, $data, $phase, $filename, $linenum) = @_; + my ($package, $symbol, $referent, $attr, $data, $phase, + $filename, $linenum) = @_; print STDERR ref($referent), " ", *{$symbol}{NAME}, " ", @@ -364,9 +365,9 @@ This creates a handler for the attribute C<:Loud> in the class LoudDecl. Thereafter, any subroutine declared with a C<:Loud> attribute in the class LoudDecl: - package LoudDecl; - - sub foo: Loud {...} + package LoudDecl; + + sub foo: Loud {...} causes the above handler to be invoked, and passed: @@ -409,11 +410,11 @@ the line number in this file. Likewise, declaring any variables with the C<:Loud> attribute within the package: - package LoudDecl; + package LoudDecl; - my $foo :Loud; - my @foo :Loud; - my %foo :Loud; + my $foo :Loud; + my @foo :Loud; + my %foo :Loud; will cause the handler to be called with a similar argument list (except, of course, that C<$_[2]> will be a reference to the variable). @@ -474,11 +475,11 @@ Regardless of the package in which it is declared, if a lexical variable is ascribed an attribute, the handler that is invoked is the one belonging to the package to which it is typed. For example, the following declarations: - package OtherClass; + package OtherClass; - my LoudDecl $loudobj : Loud; - my LoudDecl @loudobjs : Loud; - my LoudDecl %loudobjex : Loud; + my LoudDecl $loudobj : Loud; + my LoudDecl @loudobjs : Loud; + my LoudDecl %loudobjex : Loud; causes the LoudDecl::Loud handler to be invoked (even if OtherClass also defines a handler for C<:Loud> attributes). @@ -491,40 +492,40 @@ given the name of a built-in type (C<SCALAR>, C<ARRAY>, C<HASH>, or C<CODE>), the handler is only applied to declarations of that type. For example, the following definition: - package LoudDecl; + package LoudDecl; - sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" } + sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" } creates an attribute handler that applies only to scalars: - package Painful; - use base LoudDecl; + package Painful; + use base LoudDecl; - my $metal : RealLoud; # invokes &LoudDecl::RealLoud - my @metal : RealLoud; # error: unknown attribute - my %metal : RealLoud; # error: unknown attribute - sub metal : RealLoud {...} # error: unknown attribute + my $metal : RealLoud; # invokes &LoudDecl::RealLoud + my @metal : RealLoud; # error: unknown attribute + my %metal : RealLoud; # error: unknown attribute + sub metal : RealLoud {...} # error: unknown attribute You can, of course, declare separate handlers for these types as well (but you'll need to specify C<no warnings 'redefine'> to do it quietly): - package LoudDecl; - use Attribute::Handlers; - no warnings 'redefine'; + package LoudDecl; + use Attribute::Handlers; + no warnings 'redefine'; - sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" } - sub RealLoud :ATTR(ARRAY) { print "Urrrrrrrrrr!" } - sub RealLoud :ATTR(HASH) { print "Arrrrrgggghhhhhh!" } - sub RealLoud :ATTR(CODE) { croak "Real loud sub torpedoed" } + sub RealLoud :ATTR(SCALAR) { print "Yeeeeow!" } + sub RealLoud :ATTR(ARRAY) { print "Urrrrrrrrrr!" } + sub RealLoud :ATTR(HASH) { print "Arrrrrgggghhhhhh!" } + sub RealLoud :ATTR(CODE) { croak "Real loud sub torpedoed" } You can also explicitly indicate that a single handler is meant to be used for all types of referents like so: - package LoudDecl; - use Attribute::Handlers; + package LoudDecl; + use Attribute::Handlers; - sub SeriousLoud :ATTR(ANY) { warn "Hearing loss imminent" } + sub SeriousLoud :ATTR(ANY) { warn "Hearing loss imminent" } (I.e. C<ATTR(ANY)> is a synonym for C<:ATTR>). @@ -538,14 +539,14 @@ the handler get in the way. You can turn off that eagerness-to-help by declaring an attribute handler with the keyword C<RAWDATA>. For example: - sub Raw : ATTR(RAWDATA) {...} - sub Nekkid : ATTR(SCALAR,RAWDATA) {...} - sub Au::Naturale : ATTR(RAWDATA,ANY) {...} + sub Raw : ATTR(RAWDATA) {...} + sub Nekkid : ATTR(SCALAR,RAWDATA) {...} + sub Au::Naturale : ATTR(RAWDATA,ANY) {...} Then the handler makes absolutely no attempt to interpret the data it receives and simply passes it as a string: - my $power : Raw(1..100); # handlers receives "1..100" + my $power : Raw(1..100); # handlers receives "1..100" =head2 Phase-specific attribute handlers @@ -559,11 +560,11 @@ other points in the program's compilation or execution, by explicitly stating the phase (or phases) in which you wish the attribute handler to be called. For example: - sub Early :ATTR(SCALAR,BEGIN) {...} - sub Normal :ATTR(SCALAR,CHECK) {...} - sub Late :ATTR(SCALAR,INIT) {...} - sub Final :ATTR(SCALAR,END) {...} - sub Bookends :ATTR(SCALAR,BEGIN,END) {...} + sub Early :ATTR(SCALAR,BEGIN) {...} + sub Normal :ATTR(SCALAR,CHECK) {...} + sub Late :ATTR(SCALAR,INIT) {...} + sub Final :ATTR(SCALAR,END) {...} + sub Bookends :ATTR(SCALAR,BEGIN,END) {...} As the last example indicates, a handler may be set up to be (re)called in two or more phases. The phase name is passed as the handler's final argument. @@ -578,24 +579,24 @@ subsequently defined C<BEGIN> blocks are executed). Attributes make an excellent and intuitive interface through which to tie variables. For example: - use Attribute::Handlers; - use Tie::Cycle; - - sub UNIVERSAL::Cycle : ATTR(SCALAR) { - my ($package, $symbol, $referent, $attr, $data, $phase) = @_; - $data = [ $data ] unless ref $data eq 'ARRAY'; - tie $$referent, 'Tie::Cycle', $data; - } - - # and thereafter... - - package main; + use Attribute::Handlers; + use Tie::Cycle; + + sub UNIVERSAL::Cycle : ATTR(SCALAR) { + my ($package, $symbol, $referent, $attr, $data, $phase) = @_; + $data = [ $data ] unless ref $data eq 'ARRAY'; + tie $$referent, 'Tie::Cycle', $data; + } - my $next : Cycle('A'..'Z'); # $next is now a tied variable + # and thereafter... - while (<>) { - print $next; - } + package main; + + my $next : Cycle('A'..'Z'); # $next is now a tied variable + + while (<>) { + print $next; + } Note that, because the C<Cycle> attribute receives its arguments in the C<$data> variable, if the attribute is given a list of arguments, C<$data> @@ -604,16 +605,16 @@ single argument directly. Since Tie::Cycle requires its cycling values to be passed as an array reference, this means that we need to wrap non-array-reference arguments in an array constructor: - $data = [ $data ] unless ref $data eq 'ARRAY'; + $data = [ $data ] unless ref $data eq 'ARRAY'; Typically, however, things are the other way around: the tieable class expects its arguments as a flattened list, so the attribute looks like: - sub UNIVERSAL::Cycle : ATTR(SCALAR) { - my ($package, $symbol, $referent, $attr, $data, $phase) = @_; - my @data = ref $data eq 'ARRAY' ? @$data : $data; - tie $$referent, 'Tie::Whatever', @data; - } + sub UNIVERSAL::Cycle : ATTR(SCALAR) { + my ($package, $symbol, $referent, $attr, $data, $phase) = @_; + my @data = ref $data eq 'ARRAY' ? @$data : $data; + tie $$referent, 'Tie::Whatever', @data; + } This software pattern is so widely applicable that Attribute::Handlers @@ -621,16 +622,17 @@ provides a way to automate it: specifying C<'autotie'> in the C<use Attribute::Handlers> statement. So, the cycling example, could also be written: - use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' }; + use Attribute::Handlers autotie => { Cycle => 'Tie::Cycle' }; - # and thereafter... + # and thereafter... - package main; + package main; - my $next : Cycle(['A'..'Z']); # $next is now a tied variable + my $next : Cycle(['A'..'Z']); # $next is now a tied variable - while (<>) { - print $next; + while (<>) { + print $next; + } Note that we now have to pass the cycling values as an array reference, since the C<autotie> mechanism passes C<tie> a list of arguments as a list @@ -646,28 +648,29 @@ Attribute::Handlers takes care of that automagically. You can even pass arguments to the module's C<import> subroutine, by appending them to the class name. For example: - use Attribute::Handlers - autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' }; + use Attribute::Handlers + autotie => { Dir => 'Tie::Dir qw(DIR_UNLINK)' }; If the attribute name is unqualified, the attribute is installed in the current package. Otherwise it is installed in the qualifier's package: - package Here; - - use Attribute::Handlers autotie => { - Other::Good => Tie::SecureHash, # tie attr installed in Other:: - Bad => Tie::Taxes, # tie attr installed in Here:: - UNIVERSAL::Ugly => Software::Patent # tie attr installed everywhere - }; + package Here; + + use Attribute::Handlers autotie => { + Other::Good => Tie::SecureHash, # tie attr installed in Other:: + Bad => Tie::Taxes, # tie attr installed in Here:: + UNIVERSAL::Ugly => Software::Patent # tie attr installed everywhere + }; Autoties are most commonly used in the module to which they actually tie, and need to export their attributes to any module that calls them. To facilitate this, Attribute::Handlers recognizes a special "pseudo-class" -- C<__CALLER__>, which may be specified as the qualifier of an attribute: - package Tie::Me::Kangaroo:Down::Sport; - - use Attribute::Handlers autotie => { '__CALLER__::Roo' => __PACKAGE__ }; + package Tie::Me::Kangaroo:Down::Sport; + + use Attribute::Handlers autotie => + { '__CALLER__::Roo' => __PACKAGE__ }; This causes Attribute::Handlers to define the C<Roo> attribute in the package that imports the Tie::Me::Kangaroo:Down::Sport module. @@ -682,22 +685,22 @@ to the TIESCALAR, TIEHASH, etc. that ties it. The C<autotie> mechanism supports this too. The following code: - use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; - my $var : Selfish(@args); + use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; + my $var : Selfish(@args); has the same effect as: - tie my $var, 'Tie::Selfish', @args; + tie my $var, 'Tie::Selfish', @args; But when C<"autotieref"> is used instead of C<"autotie">: - use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; - my $var : Selfish(@args); + use Attribute::Handlers autotieref => { Selfish => Tie::Selfish }; + my $var : Selfish(@args); the effect is to pass the C<tie> call an extra reference to the variable being tied: - tie my $var, 'Tie::Selfish', \$var, @args; + tie my $var, 'Tie::Selfish', \$var, @args; @@ -706,142 +709,142 @@ being tied: If the class shown in L</SYNOPSIS> were placed in the MyClass.pm module, then the following code: - package main; - use MyClass; + package main; + use MyClass; - my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); + my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); - package SomeOtherClass; - use base MyClass; + package SomeOtherClass; + use base MyClass; - sub tent { 'acle' } + sub tent { 'acle' } - sub fn :Ugly(sister) :Omni('po',tent()) {...} - my @arr :Good :Omni(s/cie/nt/); - my %hsh :Good(q/bye/) :Omni(q/bus/); + sub fn :Ugly(sister) :Omni('po',tent()) {...} + my @arr :Good :Omni(s/cie/nt/); + my %hsh :Good(q/bye/) :Omni(q/bus/); would cause the following handlers to be invoked: - # my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); - - MyClass::Good:ATTR(SCALAR)( 'MyClass', # class - 'LEXICAL', # no typeglob - \$slr, # referent - 'Good', # attr name - undef # no attr data - 'CHECK', # compiler phase - ); - - MyClass::Bad:ATTR(SCALAR)( 'MyClass', # class - 'LEXICAL', # no typeglob - \$slr, # referent - 'Bad', # attr name - 0 # eval'd attr data - 'CHECK', # compiler phase - ); - - MyClass::Omni:ATTR(SCALAR)( 'MyClass', # class - 'LEXICAL', # no typeglob - \$slr, # referent - 'Omni', # attr name - '-vorous' # eval'd attr data - 'CHECK', # compiler phase - ); - - - # sub fn :Ugly(sister) :Omni('po',tent()) {...} - - MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass', # class - \*SomeOtherClass::fn, # typeglob - \&SomeOtherClass::fn, # referent - 'Ugly', # attr name - 'sister' # eval'd attr data - 'CHECK', # compiler phase - ); - - MyClass::Omni:ATTR(CODE)( 'SomeOtherClass', # class - \*SomeOtherClass::fn, # typeglob - \&SomeOtherClass::fn, # referent - 'Omni', # attr name - ['po','acle'] # eval'd attr data - 'CHECK', # compiler phase - ); - - - # my @arr :Good :Omni(s/cie/nt/); - - MyClass::Good:ATTR(ARRAY)( 'SomeOtherClass', # class - 'LEXICAL', # no typeglob - \@arr, # referent - 'Good', # attr name - undef # no attr data - 'CHECK', # compiler phase - ); - - MyClass::Omni:ATTR(ARRAY)( 'SomeOtherClass', # class - 'LEXICAL', # no typeglob - \@arr, # referent - 'Omni', # attr name - "" # eval'd attr data - 'CHECK', # compiler phase - ); - - - # my %hsh :Good(q/bye) :Omni(q/bus/); - - MyClass::Good:ATTR(HASH)( 'SomeOtherClass', # class - 'LEXICAL', # no typeglob - \%hsh, # referent - 'Good', # attr name - 'q/bye' # raw attr data - 'CHECK', # compiler phase - ); - - MyClass::Omni:ATTR(HASH)( 'SomeOtherClass', # class - 'LEXICAL', # no typeglob - \%hsh, # referent - 'Omni', # attr name - 'bus' # eval'd attr data - 'CHECK', # compiler phase - ); + # my MyClass $slr :Good :Bad(1**1-1) :Omni(-vorous); + + MyClass::Good:ATTR(SCALAR)( 'MyClass', # class + 'LEXICAL', # no typeglob + \$slr, # referent + 'Good', # attr name + undef # no attr data + 'CHECK', # compiler phase + ); + + MyClass::Bad:ATTR(SCALAR)( 'MyClass', # class + 'LEXICAL', # no typeglob + \$slr, # referent + 'Bad', # attr name + 0 # eval'd attr data + 'CHECK', # compiler phase + ); + + MyClass::Omni:ATTR(SCALAR)( 'MyClass', # class + 'LEXICAL', # no typeglob + \$slr, # referent + 'Omni', # attr name + '-vorous' # eval'd attr data + 'CHECK', # compiler phase + ); + + + # sub fn :Ugly(sister) :Omni('po',tent()) {...} + + MyClass::UGLY:ATTR(CODE)( 'SomeOtherClass', # class + \*SomeOtherClass::fn, # typeglob + \&SomeOtherClass::fn, # referent + 'Ugly', # attr name + 'sister' # eval'd attr data + 'CHECK', # compiler phase + ); + + MyClass::Omni:ATTR(CODE)( 'SomeOtherClass', # class + \*SomeOtherClass::fn, # typeglob + \&SomeOtherClass::fn, # referent + 'Omni', # attr name + ['po','acle'] # eval'd attr data + 'CHECK', # compiler phase + ); + + + # my @arr :Good :Omni(s/cie/nt/); + + MyClass::Good:ATTR(ARRAY)( 'SomeOtherClass', # class + 'LEXICAL', # no typeglob + \@arr, # referent + 'Good', # attr name + undef # no attr data + 'CHECK', # compiler phase + ); + + MyClass::Omni:ATTR(ARRAY)( 'SomeOtherClass', # class + 'LEXICAL', # no typeglob + \@arr, # referent + 'Omni', # attr name + "" # eval'd attr data + 'CHECK', # compiler phase + ); + + + # my %hsh :Good(q/bye) :Omni(q/bus/); + + MyClass::Good:ATTR(HASH)( 'SomeOtherClass', # class + 'LEXICAL', # no typeglob + \%hsh, # referent + 'Good', # attr name + 'q/bye' # raw attr data + 'CHECK', # compiler phase + ); + + MyClass::Omni:ATTR(HASH)( 'SomeOtherClass', # class + 'LEXICAL', # no typeglob + \%hsh, # referent + 'Omni', # attr name + 'bus' # eval'd attr data + 'CHECK', # compiler phase + ); Installing handlers into UNIVERSAL, makes them...err..universal. For example: - package Descriptions; - use Attribute::Handlers; + package Descriptions; + use Attribute::Handlers; - my %name; - sub name { return $name{$_[2]}||*{$_[1]}{NAME} } + my %name; + sub name { return $name{$_[2]}||*{$_[1]}{NAME} } - sub UNIVERSAL::Name :ATTR { - $name{$_[2]} = $_[4]; - } + sub UNIVERSAL::Name :ATTR { + $name{$_[2]} = $_[4]; + } - sub UNIVERSAL::Purpose :ATTR { - print STDERR "Purpose of ", &name, " is $_[4]\n"; - } + sub UNIVERSAL::Purpose :ATTR { + print STDERR "Purpose of ", &name, " is $_[4]\n"; + } - sub UNIVERSAL::Unit :ATTR { - print STDERR &name, " measured in $_[4]\n"; - } + sub UNIVERSAL::Unit :ATTR { + print STDERR &name, " measured in $_[4]\n"; + } Let's you write: - use Descriptions; + use Descriptions; - my $capacity : Name(capacity) - : Purpose(to store max storage capacity for files) - : Unit(Gb); + my $capacity : Name(capacity) + : Purpose(to store max storage capacity for files) + : Unit(Gb); - package Other; + package Other; - sub foo : Purpose(to foo all data before barring it) { } + sub foo : Purpose(to foo all data before barring it) { } - # etc. + # etc. =head1 UTILITY FUNCTIONS @@ -851,7 +854,7 @@ This module offers a single utility function, C<findsym()>. =item findsym - my $symbol = Attribute::Handlers::findsym($package, $referent); + my $symbol = Attribute::Handlers::findsym($package, $referent); The function looks in the symbol table of C<$package> for the typeglob for C<$referent>, which is a reference to a variable or subroutine (SCALAR, ARRAY, |