package attributes;
-$VERSION = 0.03;
+our $VERSION = 0.06;
@EXPORT_OK = qw(get reftype);
@EXPORT = ();
#
# The extra trips through newATTRSUB in the interpreter wipe out any savings
# from avoiding the BEGIN block. Just do the bootstrap now.
-BEGIN { bootstrap }
+BEGIN { bootstrap attributes }
sub import {
@_ > 2 && ref $_[2] or do {
=head1 SYNOPSIS
sub foo : method ;
- my ($x,@y,%z) : Bent ;
+ my ($x,@y,%z) : Bent = 1;
my $s = sub : method { ... };
use attributes (); # optional, to get subroutine declarations
The second example in the synopsis does something equivalent to this:
- use attributes __PACKAGE__, \$x, 'Bent';
- use attributes __PACKAGE__, \@y, 'Bent';
- use attributes __PACKAGE__, \%z, 'Bent';
+ use attributes ();
+ my ($x,@y,%z);
+ attributes::->import(__PACKAGE__, \$x, 'Bent');
+ attributes::->import(__PACKAGE__, \@y, 'Bent');
+ attributes::->import(__PACKAGE__, \%z, 'Bent');
+ ($x,@y,%z) = 1;
-Yes, that's three invocations.
+Yes, that's a lot of expansion.
-B<WARNING>: attribute declarations for variables are an I<experimental>
-feature. The semantics of such declarations could change or be removed
-in future versions. They are present for purposes of experimentation
+B<WARNING>: attribute declarations for variables are still evolving.
+The semantics and interfaces of such declarations could change in
+future versions. They are present for purposes of experimentation
with what the semantics ought to be. Do not rely on the current
implementation of this feature.
package-specific attributes are allowed by an extension mechanism.
(See L<"Package-specific Attribute Handling"> below.)
-The setting of attributes happens at compile time. An attempt to set
-an unrecognized attribute is a fatal error. (The error is trappable, but
-it still stops the compilation within that C<eval>.) Setting an attribute
-with a name that's all lowercase letters that's not a built-in attribute
-(such as "foo")
-will result in a warning with B<-w> or C<use warnings 'reserved'>.
+The setting of subroutine attributes happens at compile time.
+Variable attributes in C<our> declarations are also applied at compile time.
+However, C<my> variables get their attributes applied at run-time.
+This means that you have to I<reach> the run-time component of the C<my>
+before those attributes will get applied. For example:
+
+ my $x : Bent = 42 if 0;
+
+will neither assign 42 to $x I<nor> will it apply the C<Bent> attribute
+to the variable.
+
+An attempt to set an unrecognized attribute is a fatal error. (The
+error is trappable, but it still stops the compilation within that
+C<eval>.) Setting an attribute with a name that's all lowercase
+letters that's not a built-in attribute (such as "foo") will result in
+a warning with B<-w> or C<use warnings 'reserved'>.
=head2 Built-in Attributes
as described there. It also means that a subroutine so marked
will not trigger the "Ambiguous call resolved as CORE::%s" warning.
+=item lvalue
+
+Indicates that the referenced subroutine is a valid lvalue and can
+be assigned to. The subroutine must return a modifiable value such
+as a scalar variable, as described in L<perlsub>.
+
=back
-There are no built-in attributes for anything other than subroutines.
+For global variables there is C<unique> attribute: see L<perlfunc/our>.
=head2 Available Subroutines
This method is called with two fixed arguments, followed by the list of
attributes from the relevant declaration. The two fixed arguments are
the relevant package name and a reference to the declared subroutine or
-variable. The expected return value as a list of attributes which were
+variable. The expected return value is a list of attributes which were
not recognized by this handler. Note that this allows for a derived class
to delegate a call to its base class, and then only examine the attributes
which the base class didn't already handle for it.
Effect:
- use attributes Canine => \$spot, "Watchful";
+ use attributes ();
+ attributes::->import(Canine => \$spot, "Watchful");
=item 2.
Effect:
- use attributes Felis => \$cat, "Nervous";
+ use attributes ();
+ attributes::->import(Felis => \$cat, "Nervous");
=item 3.