|Think about Loose Coupling|
Namespaces and importing/exporting of attributesby lodin (Hermit)
|on Aug 29, 2007 at 13:52 UTC||Need Help??|
I thought I'd try to spark some discussion. (Perhaps this has been discussed elsewhere. In that case, please point me in the right direction.)
Recently I posted that I wanted a better attributes implementation for Perl 5.12. I mostly pointed out issues with the current implementation, and gave little or no suggestions on how to make it better. My top priority was the lack of attribute namespaces and an import/export mechanism. So here's my two cents.
The idea is really simple, but I haven't seen it discussed anywhere. (It's rather hard to search for discussions about attributes though as it's such an overloaded word.) I like the idea of having subroutine handlers be pure subroutines as they are today. I also like having them easily accessible in the symbol table. But obviously that'll cause a name clash if you have them in your package along with all your other subroutines and you have both a scalar and a hash attribute with the same name (and I think you should be able to have that).
The basis is of it all is to put attributes into a dedicated package, where the package name is made up of three parts:
An example: let's say I have an array attribute Sorted that I want to use in package Foo. Then the handler could be stored in for instance package attributes::ARRAY::Foo, i.e. as &attributes::ARRAY::Foo::Sorted. (The top-level package part being "attributes" was arbitrarily chosen.) This would make it easy to manipulate attribute handlers (such as import/export, but also to use attributes on them). No extra module would be required to define attributes, and I think that's good. It's a bit cumbersome to switch package, but convenience modules could be used to ease things up.
This could also be easily incorporated to Exporter and other exporter modules. My proposal for syntax would be @:Sorted to import/export the array attribute Sorted. It reads well I think.
I've prototyped this by writing my own MODIFY_*TYPE*_ATTRIBUTES and an exporter I called Exporter::Attributes (a drop-in replacement subclassing Exporter). I rather liked it.
One issue is still left though and that is how a variable/subroutine in package Foo can use Bar's attributes. :Bar::Attrname is currently illegal. What I'd really like is :Bar::Attrname to be legal. But if that can't happen my current favourite is to create a special :apply attribute (needn't be built-in) used like :apply($attr, @args). That would be handy for applying dynamically determined attributes, but it would also have little restrictions on what $attr could be. (This of course assuming that attributes can take arguments and not just an annotation.)
Any thoughts about this scheme? Is it sane? Is it doable? Is it realistic for Perl 5.12?