1N/A## forward declaration(s) rather than wrapping the bootstrap call in BEGIN{} 1N/A#sub _fetch_attrs ($) ; 1N/A#sub _guess_stash ($) ; 1N/A#sub _warn_reserved () ; 1N/A# The extra trips through newATTRSUB in the interpreter wipe out any savings 1N/A# from avoiding the BEGIN block. Just do the bootstrap now. 1N/A @_ >
2 &&
ref $_[
2]
or do {
1N/A carp "$svtype package attribute$s " .
1N/A "may clash with future reserved word$s: " .
1N/A croak "Invalid $svtype attribute" .
1N/A @_ ==
1 &&
ref $_[
0]
or 1N/Aattributes - get/set subroutine or variable attributes 1N/A my ($x,@y,%z) : Bent = 1; 1N/A my $s = sub : method { ... }; 1N/A use attributes (); # optional, to get subroutine declarations 1N/A my @attrlist = attributes::get(\&foo); 1N/A use attributes 'get'; # import the attributes::get subroutine 1N/A my @attrlist = get \&foo; 1N/ASubroutine declarations and definitions may optionally have attribute lists 1N/Aassociated with them. (Variable C<my> declarations also may, but see the 1N/Awarning below.) Perl handles these declarations by passing some information 1N/Aabout the call site and the thing being declared along with the attribute 1N/Alist to this module. In particular, the first example above is equivalent to 1N/A use attributes __PACKAGE__, \&foo, 'method'; 1N/AThe second example in the synopsis does something equivalent to this: 1N/A attributes::->import(__PACKAGE__, \$x, 'Bent'); 1N/A attributes::->import(__PACKAGE__, \@y, 'Bent'); 1N/A attributes::->import(__PACKAGE__, \%z, 'Bent'); 1N/AYes, that's a lot of expansion. 1N/AB<WARNING>: attribute declarations for variables are still evolving. 1N/AThe semantics and interfaces of such declarations could change in 1N/Afuture versions. They are present for purposes of experimentation 1N/Awith what the semantics ought to be. Do not rely on the current 1N/Aimplementation of this feature. 1N/AThere are only a few attributes currently handled by Perl itself (or 1N/Adirectly by this module, depending on how you look at it.) However, 1N/Apackage-specific attributes are allowed by an extension mechanism. 1N/A(See L<"Package-specific Attribute Handling"> below.) 1N/AThe setting of subroutine attributes happens at compile time. 1N/AVariable attributes in C<our> declarations are also applied at compile time. 1N/AHowever, C<my> variables get their attributes applied at run-time. 1N/AThis means that you have to I<reach> the run-time component of the C<my> 1N/Abefore those attributes will get applied. For example: 1N/A my $x : Bent = 42 if 0; 1N/Awill neither assign 42 to $x I<nor> will it apply the C<Bent> attribute 1N/AAn attempt to set an unrecognized attribute is a fatal error. (The 1N/Aerror is trappable, but it still stops the compilation within that 1N/AC<eval>.) Setting an attribute with a name that's all lowercase 1N/Aletters that's not a built-in attribute (such as "foo") will result in 1N/Aa warning with B<-w> or C<use warnings 'reserved'>. 1N/A=head2 Built-in Attributes 1N/AThe following are the built-in attributes for subroutines: 1N/AB<5.005 threads only! The use of the "locked" attribute currently 1N/Aonly makes sense if you are using the deprecated "Perl 5.005 threads" 1N/Aimplementation of threads.> 1N/ASetting this attribute is only meaningful when the subroutine or 1N/Amethod is to be called by multiple threads. When set on a method 1N/Asubroutine (i.e., one marked with the B<method> attribute below), 1N/APerl ensures that any invocation of it implicitly locks its first 1N/Aargument before execution. When set on a non-method subroutine, 1N/APerl ensures that a lock is taken on the subroutine itself before 1N/Aexecution. The semantics of the lock are exactly those of one 1N/Aexplicitly taken with the C<lock> operator immediately after the 1N/Asubroutine is entered. 1N/AIndicates that the referenced subroutine is a method. 1N/AThis has a meaning when taken together with the B<locked> attribute, 1N/Aas described there. It also means that a subroutine so marked 1N/Awill not trigger the "Ambiguous call resolved as CORE::%s" warning. 1N/AIndicates that the referenced subroutine is a valid lvalue and can 1N/Abe assigned to. The subroutine must return a modifiable value such 1N/Aas a scalar variable, as described in L<perlsub>. 1N/AFor global variables there is C<unique> attribute: see L<perlfunc/our>. 1N/A=head2 Available Subroutines 1N/AThe following subroutines are available for general use once this module 1N/AThis routine expects a single parameter--a reference to a 1N/Asubroutine or variable. It returns a list of attributes, which may be 1N/Aempty. If passed invalid arguments, it uses die() (via L<Carp::croak|Carp>) 1N/Ato raise a fatal exception. If it can find an appropriate package name 1N/Afor a class method lookup, it will include the results from a 1N/AC<FETCH_I<type>_ATTRIBUTES> call in its return list, as described in 1N/AL<"Package-specific Attribute Handling"> below. 1N/AOtherwise, only L<built-in attributes|"Built-in Attributes"> will be returned. 1N/AThis routine expects a single parameter--a reference to a subroutine or 1N/Avariable. It returns the built-in type of the referenced variable, 1N/Aignoring any package into which it might have been blessed. 1N/AThis can be useful for determining the I<type> value which forms part of 1N/Athe method names described in L<"Package-specific Attribute Handling"> below. 1N/ANote that these routines are I<not> exported by default. 1N/A=head2 Package-specific Attribute Handling 1N/AB<WARNING>: the mechanisms described here are still experimental. Do not 1N/Arely on the current implementation. In particular, there is no provision 1N/Afor applying package attributes to 'cloned' copies of subroutines used as 1N/Aclosures. (See L<perlref/"Making References"> for information on closures.) 1N/APackage-specific attribute handling may change incompatibly in a future 1N/AWhen an attribute list is present in a declaration, a check is made to see 1N/Awhether an attribute 'modify' handler is present in the appropriate package 1N/A(or its @ISA inheritance tree). Similarly, when C<attributes::get> is 1N/Acalled on a valid reference, a check is made for an appropriate attribute 1N/A'fetch' handler. See L<"EXAMPLES"> to see how the "appropriate package" 1N/AThe handler names are based on the underlying type of the variable being 1N/Adeclared or of the reference passed. Because these attributes are 1N/Aassociated with subroutine or variable declarations, this deliberately 1N/Aignores any possibility of being blessed into some package. Thus, a 1N/Asubroutine declaration uses "CODE" as its I<type>, and even a blessed 1N/Ahash reference uses "HASH" as its I<type>. 1N/AThe class methods invoked for modifying and fetching are these: 1N/A=item FETCH_I<type>_ATTRIBUTES 1N/AThis method receives a single argument, which is a reference to the 1N/Avariable or subroutine for which package-defined attributes are desired. 1N/AThe expected return value is a list of associated attributes. 1N/AThis list may be empty. 1N/A=item MODIFY_I<type>_ATTRIBUTES 1N/AThis method is called with two fixed arguments, followed by the list of 1N/Aattributes from the relevant declaration. The two fixed arguments are 1N/Athe relevant package name and a reference to the declared subroutine or 1N/Avariable. The expected return value is a list of attributes which were 1N/Anot recognized by this handler. Note that this allows for a derived class 1N/Ato delegate a call to its base class, and then only examine the attributes 1N/Awhich the base class didn't already handle for it. 1N/AThe call to this method is currently made I<during> the processing of the 1N/Adeclaration. In particular, this means that a subroutine reference will 1N/Aprobably be for an undefined subroutine, even if this declaration is 1N/Aactually part of the definition. 1N/ACalling C<attributes::get()> from within the scope of a null package 1N/Adeclaration C<package ;> for an unblessed variable reference will 1N/Anot provide any starting package name for the 'fetch' method lookup. 1N/AThus, this circumstance will not result in a method call for package-defined 1N/Aattributes. A named subroutine knows to which symbol table entry it belongs 1N/A(or originally belonged), and it will use the corresponding package. 1N/AAn anonymous subroutine knows the package name into which it was compiled 1N/A(unless it was also compiled with a null package declaration), and so it 1N/Awill use that package name. 1N/A=head2 Syntax of Attribute Lists 1N/AAn attribute list is a sequence of attribute specifications, separated by 1N/Awhitespace or a colon (with optional whitespace). 1N/AEach attribute specification is a simple 1N/Aname, optionally followed by a parenthesised parameter list. 1N/AIf such a parameter list is present, it is scanned past as for the rules 1N/Afor the C<q()> operator. (See L<perlop/"Quote and Quote-like Operators">.) 1N/AThe parameter list is passed as it was found, however, and not as per C<q()>. 1N/ASome examples of syntactically valid attribute lists: 1N/A switch(10,foo(7,3)) : expensive 1N/ASome examples of syntactically invalid attribute lists (with annotation): 1N/A switch(10,foo() # ()-string not balanced 1N/A Ugly('(') # ()-string not balanced 1N/A 5x5 # "5x5" not a valid identifier 1N/A Y2::north # "Y2::north" not a simple identifier 1N/A foo + bar # "+" neither a colon nor whitespace 1N/A=head2 Default exports 1N/A=head2 Available exports 1N/AThe routines C<get> and C<reftype> are exportable. 1N/A=head2 Export tags defined 1N/AThe C<:ALL> tag will get all of the above exports. 1N/AHere are some samples of syntactically valid declarations, with annotation 1N/Aas to how they resolve internally into C<use attributes> invocations by 1N/Aperl. These examples are primarily useful to see how the "appropriate 1N/Apackage" is found for the possible method lookups for package-defined 1N/A my Canine $spot : Watchful ; 1N/A attributes::->import(Canine => \$spot, "Watchful"); 1N/A attributes::->import(Felis => \$cat, "Nervous"); 1N/A use attributes X => \&foo, "locked"; 1N/A sub Y::x : locked { 1 } 1N/A use attributes Y => \&Y::x, "locked"; 1N/A BEGIN { *bar = \&X::foo; } 1N/A sub Y::bar : locked ; 1N/A use attributes X => \&X::foo, "locked"; 1N/AThis last example is purely for purposes of completeness. You should not 1N/Abe trying to mess with the attributes of something in a package that's 1N/AL<perlsub/"Private Variables via my()"> and 1N/AL<perlsub/"Subroutine Attributes"> for details on the basic declarations; 1N/AL<attrs> for the obsolescent form of subroutine attribute specification 1N/Awhich this module replaces;