On 9 May 2010, at 02:36, Stevan Little wrote:
On May 8, 2010, at 1:27 PM, Eric Veith1 wrote:
Stevan Little <[email protected]> wrote on 05/08/2010
07:09:47
PM:
I have a serious allergy to method attributes, I don't ever use them
so I couldn't comment.
Do you mind giving me some bullet points regarding your allergy? I
found
method attributes rather appealing until now, but if there's some
serious
trouble ahead, I can still change my design (and would).
Sure, here are my basic bullets:
Nice summary. Couple of additional thoughts below.
- The attributes.pm API is horrible and requires all sorts of odd
things in order to be properly supported inheritance.
The MX::MethodAttributes hides much of this, but that's not all ...
MX::MethodAttributes _kinda_ hides this, but also involves doing
horrible horrible violence to your metaclasses which can either:
a) Ruin your day very obviously with metaclass incompatibility if
you're trying to be _too_ clever.
b) Ruin your day silently and unexpectedly by forcing a late
metaclass re-initialization and throwing all your data away.
It generally works for Catalyst / Catalyst apps, however I _strongly_
disrecommend anyone else from using it.
It also means that you end up saying:
BEGIN { extends 'Catalyst::Controller' } # Which is fairly
confusing / obscure as to why this is needed. (Attributes are applied
at compile time, and 'extends' is usually a runtime keyword)
- attributes are nothing more then strings, you must parse them
yourself.
In the simple case this is not that hard, but simple cases have a
habit of growing into complex cases over time. This kind of thing
just adds to the fragility of attributes overall.
If you need more convincing of this, go read Catalyst::Controller..
- attributes must be on a single line
C'mon, really??? This seems simple, but it is a silly restriction
that can easily trip newcomers up. Again, just added to the
fragility in my opinion.
This is entirely not true.
However if you line-break, you need to re add the :.
So these are valid:
sub foo : Bar Baz Quux {}
sub foo : Bar : Baz : Quux {}
sub foo
: Bar
: Baz
: Quux {}
But this isn't:
sub foo : Bar
Baz
Quux {}
You're entirely right about silly and fragile however.
- attributes don't actually do *anything*
Well, they do associate string metadata with a function/method, the
rest you must do yourself.
See also the _Parse_xxxx methods in Catalyst::Controller if you need
convincing this isn't any fun.
Personally I lean towards exporting keyword-like functions. I
explored method attributes for the before/after/around modifiers in
the early early days of Moose and abandoned them shortly afterwards
for all the reasons listed above.
Honestly, the way it sounds like you are using them (to "mark"
methods) is likely fine, just keep in mind that it might not scale
if your needs grow too complex.
I'd entirely go with adding a keyword like function for this instead.
The syntax isn't _quite_ as nice, but the implementation is much more
obvious in my opinion, and as noted you win a whole bunch of
extensibility if and when you need it later for free.
Cheers
t0m