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

Reply via email to