I've been playing with code attributes lately. I'm using them to annotate
introspection hints on functions used for commands in an interactive
system. These annotations give help text, hints on argument parsing,
etc.. I've found Attribute::Handlers doesn't work for these because my
program dynamically reloads the code all the time, whenever things
change. It doesn't cope with them.

So, I wrote [the attached]. Not quite sure what name to call it - All the
rest in Attribute:: space seems to be specific attributes written using
Attribute::Handlers. That said, I can't find anywhere else more suited.

Thoughts, anyone? On the name, the implementation, the idea,.. anything
else that comes to mind?

-----

Attribute::Storage(3pmUser Contributed Perl DocumentatiAttribute::Storage(3pm)



NAME
       "Attribute::Storage" - store and access named attributes about CODE
       references

SYNOPSIS
        package My::Package;

        use Attribute::Storage;

        sub Title : ATTR(CODE)
        {
           my $package = shift;
           my ( $title ) = @_;

           return $title;
        }

        1;

        package main

        use Attribute::Storage qw( get_subattr );
        use My::Package;

        sub myfunc : Title('The title of my function')
        {
           ...
        }

        print "Title of myfunc is: ".get_subattr(\&myfunc, 'Title')."\n";

DESCRIPTION
       This package provides a base, where a package using it can define
       handlers for particular code attributes. Other packages, using the
       package that defines the code attributes, can then use them to annotate
       subs.

       This is similar to "Attribute::Handlers", with the following key
       differences:

       ·   "Attribute::Storage" will store the value returned by the attribute
           handling code, and provides convenient lookup functions to retrieve
           it later.  "Attribute::Handlers" simply invokes the handling code.

       ·   "Attribute::Storage" immediately executes the attribute handling
           code at compile-time.  "Attribute::Handlers" defers invocation so
           it can look up the symbolic name of the sub the attribute is
           attached to. An upshot here is that the invoked code in
           "Attribute::Storage" does not know the name of the sub it attaches
           to.

       ·   "Attribute::Storage" is safe to use on code that will be reloaded,
           because it executes handlers immediately. "Attribute::Handlers"
           will only execute handlers at defined phases such as "BEGIN" or
           "INIT", and cannot reexecute the handlers in a file once it has
           been reloaded.

ATTRIBUTES
       Each attribute that the defining package wants to define should be done
       using a marked subroutine, in a way similar to Attribute::Handlers.
       When a sub in the using package is marked with such an attribute, the
       code is executed, passing in the arguments. Whatever it returns is
       stored, to be returned later when queried by "get_subattr" or
       "get_subattrs".

        sub AttributeName : ATTR(CODE)
        {
           my $package = shift;
           my ( $attr, $args, $here ) = @_;
           ...
           return $value;
        }

       At attachment time, the optional string that may appear within brackets
       following the attribute’s name is parsed as a Perl expression in array
       context. If this succeeds, the values are passed in a list to the
       handling code. If this fails, an error is returned to the perl
       compiler. If no string is present, then an empty list is passed to the
       handling code.

        package Defining;

        sub NameMap : ATTR(CODE)
        {
           my $package = shift;
           my @strings = @_;

           return { map { m/^(.*)=(.*)$/ and ( $1, $2 ) } @strings };
        }

        package Using;

        use Defining;

        sub somefunc : NameMap("foo=FOO","bar=BAR","splot=WIBBLE") { ... }

        my $map = get_subattr("somefunc", "NameMap");
        # Will yield:
        #  { foo   => "FOO",
        #    bar   => "BAR",
        #    splot => "WIBBLE" }

       Note that it is impossible to distinguish

        sub somefunc : NameMap   { ... }
        sub somefunc : NameMap() { ... }

FUNCTIONS
   $attrs = get_subattrs( $sub )
       Returns a HASH reference containing all the attributes defined on the
       given sub. The sub should either be passed as a CODE reference, or as a
       name in the caller’s package. If no attributes are defined, a reference
       to an empty HASH is returned.

   $value = get_subattr( $sub, $attrname )
       Returns the value of a single named attribute on the given sub. The sub
       should either be passed as a CODE reference, or as a name in the
       caller’s package. If the attribute is not defined, "undef" is returned.

AUTHOR
       Paul Evans <[EMAIL PROTECTED]>



perl v5.10.0                      2008-10-20           Attribute::Storage(3pm)

-----

-- 
Paul "LeoNerd" Evans

[EMAIL PROTECTED]
ICQ# 4135350       |  Registered Linux# 179460
http://www.leonerd.org.uk/

Attachment: Attribute-Storage-0.01.tar.gz
Description: GNU Zip compressed data

Attachment: signature.asc
Description: PGP signature

Reply via email to