X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fattributes.pm;h=4f6eef03761d3a5c85bbc75333368caeffa50342;hb=cd340a5d1de2dbc931e802b4aaed98e9e4d75f51;hp=d26872f566dbd4ac06b165ea91caba762150c8c5;hpb=26f2972e6cc14b5198456611d023553a813ccb68;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/attributes.pm b/lib/attributes.pm index d26872f..4f6eef0 100644 --- a/lib/attributes.pm +++ b/lib/attributes.pm @@ -1,6 +1,6 @@ package attributes; -$VERSION = 0.02; +our $VERSION = '0.04_01'; @EXPORT_OK = qw(get reftype); @EXPORT = (); @@ -27,13 +27,13 @@ sub carp { # # 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 { require Exporter; goto &Exporter::import; - } + }; my (undef,$home_stash,$svref,@attrs) = @_; my $svtype = uc reftype($svref); @@ -54,7 +54,7 @@ sub import { my $s = ((@pkgattrs == 1) ? '' : 's'); carp "$svtype package attribute$s " . "may clash with future reserved word$s: " . - join(' , ' , @pkgattrs); + join(' : ' , @pkgattrs); } } } @@ -65,7 +65,7 @@ sub import { croak "Invalid $svtype attribute" . (( @badattrs == 1 ) ? '' : 's') . ": " . - join(' , ', @badattrs); + join(' : ', @badattrs); } } @@ -98,7 +98,7 @@ attributes - get/set subroutine or variable attributes =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 @@ -120,11 +120,14 @@ the following: 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: attribute declarations for variables are an I feature. The semantics of such declarations could change or be removed @@ -137,7 +140,18 @@ directly by this module, depending on how you look at it.) However, 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 +The setting of subroutine attributes happens at compile time. +Variable attributes in C declarations are also applied at compile time. +However, C variables get their attributes applied at run-time. +This means that you have to I the run-time component of the C +before those attributes will get applied. For example: + + my $x : Bent = 42 if 0; + +will neither assign 42 to $x I will it apply the C 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.) Setting an attribute with a name that's all lowercase letters that's not a built-in attribute @@ -169,10 +183,19 @@ This has a meaning when taken together with the B attribute, 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. + =back There are no built-in attributes for anything other than subroutines. +=for hackers +What about C? + =head2 Available Subroutines The following subroutines are available for general use once this module @@ -267,7 +290,8 @@ will use that package name. =head2 Syntax of Attribute Lists An attribute list is a sequence of attribute specifications, separated by -whitespace, commas, or both. Each attribute specification is a simple +whitespace or a colon (with optional whitespace). +Each attribute specification is a simple name, optionally followed by a parenthesised parameter list. If such a parameter list is present, it is scanned past as for the rules for the C operator. (See L.) @@ -275,8 +299,8 @@ The parameter list is passed as it was found, however, and not as per C. Some examples of syntactically valid attribute lists: - switch(10,foo(7,3)) , , expensive - Ugly('\(") , Bad + switch(10,foo(7,3)) : expensive + Ugly('\(") :Bad _5x5 locked method @@ -286,7 +310,7 @@ Some examples of syntactically invalid attribute lists (with annotation): Ugly('(') # ()-string not balanced 5x5 # "5x5" not a valid identifier Y2::north # "Y2::north" not a simple identifier - foo + bar # "+" neither a comma nor whitespace + foo + bar # "+" neither a colon nor whitespace =head1 EXPORTS @@ -322,7 +346,8 @@ Code: Effect: - use attributes Canine => \$spot, "Watchful"; + use attributes (); + attributes::->import(Canine => \$spot, "Watchful"); =item 2. @@ -333,7 +358,8 @@ Code: Effect: - use attributes Felis => \$cat, "Nervous"; + use attributes (); + attributes::->import(Felis => \$cat, "Nervous"); =item 3.