Skip Menu |

This queue is for tickets about the MooseX-MethodAttributes CPAN distribution.

Report information
The Basics
Id: 90126
Status: open
Priority: 0/
Queue: MooseX-MethodAttributes

People
Owner: Nobody in particular
Requestors: l.mai [...] web.de
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.28
Fixed in: (no value)



Subject: anon sub attrs silently ignored under perl -d
% cat wtf.t #!perl use strict; use warnings; use Test::More tests => 1; { package Zomg; use Moose; use MooseX::MethodAttributes; no warnings 'once'; *foo = sub : Hello {}; } is_deeply +Zomg->meta->get_method('foo')->attributes, ['Hello']; __END__ % perl wtf.t 1..1 ok 1 % PERLDB_OPTS=NonStop perl -d wtf.t 1..1 not ok 1 # Failed test at wtf.t line 17. # Structures begin differing at: # $got->[0] = Does not exist # $expected->[0] = 'Hello' # Looks like you failed 1 test of 1. => Subroutine attributes are silently ignored under perl -d. This bug also affects Method::Signatures and similar modules because they use anonymous subs + glob assignment internally. This in turn interacts badly with Catalyst. Take a controller like this: { package Foo::Controller::Product; use Moose; use syntax 'method'; BEGIN { extends 'Catalyst::Controller' } method list($ctx) : Path Args(0) { ... } } Catalyst uses MooseX::MethodAttributes to handle attributes to register actions. Syntax::Feature::Method uses Method::Signatures::Simple, which uses glob assignment to define methods. The result is that visiting /product gives a 404 error (because no actions got registered) but only if the debugger is active. Unfortunately this also breaks profiling (Devel::NYTProf) because it's implemented using -d (possibly coverage checks (Devel::Cover) too, I haven't checked).
Subject: wtf.t
#!perl use strict; use warnings; use Test::More tests => 1; { package Zomg; use Moose; use MooseX::MethodAttributes; no warnings 'once'; *foo = sub : Hello {}; } is_deeply +Zomg->meta->get_method('foo')->attributes, ['Hello']; __END__
From: l.mai [...] web.de
Possibly interesting data points: 1) Lifting the glob assignment to compile time (as in 'BEGIN { *foo = sub : Hello {}; }' does not help. 2) Using Function::Parameters instead of Method::Signatures::Simple does help: use Function::Parameters qw(:strict); method foo : Hello {} # OK And it keeps working even if you delay the method definition to runtime: use Function::Parameters { method => { defaults => 'method_strict', runtime => 1 } }; method foo : Hello {} # still OK
This seems to be a problem with perl itself: https://rt.perl.org/Ticket/Display.html?id=120500
On Sat Nov 09 17:39:36 2013, MAUKE wrote: Show quoted text
> This seems to be a problem with perl itself: > https://rt.perl.org/Ticket/Display.html?id=120500
I've found a (slightly ridiculous?) workaround (see attached patch). I've applied it to a test Catalyst app and it seems to work great.
Subject: mx_ma_anonsub.patch
--- /home/mauke/usr/local/lib/perl5/site_perl/5.18.1/MooseX/MethodAttributes/Role/AttrContainer.pm 2012-09-04 05:28:33.000000000 +0200 +++ lib/MooseX/MethodAttributes/Role/AttrContainer.pm 2013-11-10 19:33:59.000000000 +0100 @@ -10,11 +10,31 @@ use Moose::Role; use Moose::Util qw/find_meta/; +use attributes (); +use B qw(svref_2object CVf_CLONE); +use Variable::Magic qw(wizard cast); + use namespace::clean -except => 'meta'; +my $wizard; BEGIN { + $wizard = wizard( + data => sub { shift; [@_] }, + copy => sub { + my ($class, @attrs) = @{$_[1]}; + my $code = \$_[3]; # XXX - relies on #90205 in Variable::Magic + attributes->import($class, $code, @attrs); + }, + ); +} sub MODIFY_CODE_ATTRIBUTES { my ($class, $code, @attrs) = @_; + my $cv = svref_2object $code; + my $is_proto = $cv->CvFLAGS & CVf_CLONE; + if ($is_proto) { + cast &$code, $wizard, $class, @attrs; + return (); + } find_meta($class)->register_method_attributes($code, \@attrs); return (); }