This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Text::ParseWords 3.27
[perl5.git] / lib / attributes.pm
index dfe892a..aa532c2 100644 (file)
@@ -1,6 +1,6 @@
 package attributes;
 
-our $VERSION = 0.06;
+our $VERSION = 0.09;
 
 @EXPORT_OK = qw(get reftype);
 @EXPORT = ();
@@ -23,7 +23,6 @@ sub carp {
 #sub _fetch_attrs ($) ;
 #sub _guess_stash ($) ;
 #sub _modify_attrs ;
-#sub _warn_reserved () ;
 #
 # The extra trips through newATTRSUB in the interpreter wipe out any savings
 # from avoiding the BEGIN block.  Just do the bootstrap now.
@@ -43,9 +42,10 @@ sub import {
     my @badattrs;
     if ($pkgmeth) {
        my @pkgattrs = _modify_attrs($svref, @attrs);
-       @badattrs = $pkgmeth->($home_stash, $svref, @attrs);
+       @badattrs = $pkgmeth->($home_stash, $svref, @pkgattrs);
        if (!@badattrs && @pkgattrs) {
-           return unless _warn_reserved;
+            require warnings;
+           return unless warnings::enabled('reserved');
            @pkgattrs = grep { m/\A[[:lower:]]+(?:\z|\()/ } @pkgattrs;
            if (@pkgattrs) {
                for my $attr (@pkgattrs) {
@@ -157,6 +157,37 @@ 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 What C<import> does
+
+In the description it is mentioned that
+
+  sub foo : method;
+
+is equivalent to
+
+  use attributes __PACKAGE__, \&foo, 'method';
+
+As you might know this calls the C<import> function of C<attributes> at compile 
+time with these parameters: 'attributes', the caller's package name, the reference 
+to the code and 'method'.
+
+  attributes->import( __PACKAGE__, \&foo, 'method' );
+
+So you want to know what C<import> actually does?
+
+First of all C<import> gets the type of the third parameter ('CODE' in this case).
+C<attributes.pm> checks if there is a subroutine called C<< MODIFY_<reftype>_ATTRIBUTES >>
+in the caller's namespace (here: 'main'). In this case a subroutine C<MODIFY_CODE_ATTRIBUTES> is
+required. Then this method is called to check if you have used a "bad attribute".
+The subroutine call in this example would look like
+
+  MODIFY_CODE_ATTRIBUTES( 'main', \&foo, 'method' );
+
+C<< MODIFY_<reftype>_ATTRIBUTES >> has to return a list of all "bad attributes".
+If there are any bad attributes C<import> croaks.
+
+(See L<"Package-specific Attribute Handling"> below.)
+
 =head2 Built-in Attributes
 
 The following are the built-in attributes for subroutines:
@@ -165,6 +196,10 @@ The following are the built-in attributes for subroutines:
 
 =item locked
 
+B<5.005 threads only!  The use of the "locked" attribute currently
+only makes sense if you are using the deprecated "Perl 5.005 threads"
+implementation of threads.>
+
 Setting this attribute is only meaningful when the subroutine or
 method is to be called by multiple threads.  When set on a method
 subroutine (i.e., one marked with the B<method> attribute below),
@@ -251,10 +286,10 @@ The class methods invoked for modifying and fetching are these:
 
 =item FETCH_I<type>_ATTRIBUTES
 
-This method receives a single argument, which is a reference to the
-variable or subroutine for which package-defined attributes are desired.
-The expected return value is a list of associated attributes.
-This list may be empty.
+This method is called with two arguments:  the relevant package name,
+and a reference to a variable or subroutine for which package-defined
+attributes are desired.  The expected return value is a list of
+associated attributes.  This list may be empty.
 
 =item MODIFY_I<type>_ATTRIBUTES
 
@@ -402,6 +437,52 @@ This last example is purely for purposes of completeness.  You should not
 be trying to mess with the attributes of something in a package that's
 not your own.
 
+=head1 MORE EXAMPLES
+
+=over 4
+
+=item 1.
+
+    sub MODIFY_CODE_ATTRIBUTES {
+       my ($class,$code,@attrs) = @_;
+
+       my $allowed = 'MyAttribute';
+       my @bad = grep { $_ ne $allowed } @attrs;
+
+       return @bad;
+    }
+
+    sub foo : MyAttribute {
+       print "foo\n";
+    }
+
+This example runs. At compile time C<MODIFY_CODE_ATTRIBUTES> is called. In that
+subroutine, we check if any attribute is disallowed and we return a list of
+these "bad attributes".
+
+As we return an empty list, everything is fine.
+
+=item 2.
+
+  sub MODIFY_CODE_ATTRIBUTES {
+     my ($class,$code,@attrs) = @_;
+
+     my $allowed = 'MyAttribute';
+     my @bad = grep{ $_ ne $allowed }@attrs;
+
+     return @bad;
+  }
+
+  sub foo : MyAttribute Test {
+     print "foo\n";
+  }
+
+This example is aborted at compile time as we use the attribute "Test" which
+isn't allowed. C<MODIFY_CODE_ATTRIBUTES> returns a list that contains a single
+element ('Test').
+
+=back
+
 =head1 SEE ALSO
 
 L<perlsub/"Private Variables via my()"> and