Skip Menu |

This queue is for tickets about the Moo CPAN distribution.

Report information
The Basics
Id: 87575
Status: resolved
Priority: 0/
Queue: Moo

People
Owner: Nobody in particular
Requestors: Support [...] RoxSoft.co.uk
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.003000
Fixed in: 1.003001



Subject: Deep recursion on subroutine "Method::Generate::Accessor::_SIGDIE"
I get the error Deep recursion on subroutine "Method::Generate::Accessor::_SIGDIE" when running the attached test script. The attached patched fixes it but I'm not sure that it is a genuine fix or whether I've just stumbled across it by chance. I suppose it could also be the type library but I don't think I'm doing anything strange in there.
Subject: accessor.patch
--- Accessor.orig.pm 2013-08-02 22:19:21.000000000 +0100 +++ Accessor.pm 2013-08-03 13:27:14.000000000 +0100 @@ -5,7 +5,7 @@ use base qw(Moo::Object); use Sub::Quote; use B 'perlstring'; -use Scalar::Util 'blessed'; +use Scalar::Util qw( blessed refaddr ); use overload (); use Module::Runtime qw(use_module); BEGIN { @@ -404,12 +404,19 @@ .' name => '.B::perlstring($name).",\n" .' step => '.B::perlstring($prefix).",\n" ." };\n" - .' local $Method::Generate::Accessor::OrigSigDie = $SIG{__DIE__};'."\n" - .' local $SIG{__DIE__} = \&Method::Generate::Accessor::_SIGDIE;'."\n" + .' &Method::Generate::Accessor::__is_die_set() or ('."\n" + .' local $Method::Generate::Accessor::OrigSigDie = $SIG{__DIE__} and '."\n" + .' local $SIG{__DIE__} = \&Method::Generate::Accessor::_SIGDIE);'."\n" .$inside ."}\n" } +sub __is_die_set { + return refaddr( $SIG{__DIE__} ) + && $Method::Generate::Accessor::OrigSigDie && refaddr( $SIG{__DIE__} ) + == refaddr( $Method::Generate::Accessor::OrigSigDie ) ? 1 : 0; +} + sub _generate_isa_check { my ($self, $name, $value, $check, $init_arg) = @_; $self->_generate_die_prefix(
Subject: accessor.t
# @(#)Ident: accessor.t 2013-08-03 19:05 pjf ; use strict; use warnings; { package Accessor::Test::Role; use File::DataClass::Types qw( Directory Path ); use Moo::Role; has 'dir' => is => 'lazy', isa => Directory, coerce => Directory->coercion, default => 'dummy'; has 'index' => is => 'lazy', isa => Path, coerce => Path->coercion, default => sub { $_[ 0 ]->dir->catfile( 'index.json' ) }; } { package Accessor::Test; use Moo; with q(Accessor::Test::Role); } my $prog = Accessor::Test->new(); $prog->index;
Confirmed. This is probably a better fix though: sub _SIGDIE { our ($CurrentAttribute, $OrigSigDie); my $next = sub { die $_[0] }; $next = $OrigSigDie if $OrigSigDie && refaddr($OrigSigDie)!=refaddr(\&_SIGDIE); return $next->(@_) if ref($_[0]); my $attr_desc = _attr_desc(@$CurrentAttribute{qw(name init_arg)}); $next->("$CurrentAttribute->{step} for $attr_desc failed: $_[0]"); }
On Sat Aug 03 18:29:01 2013, TOBYINK wrote: Show quoted text
> Confirmed. This is probably a better fix though:
I re-cut the patch and removed the external dependencies from the test
Subject: accessor-deep-recursion.patch
--- Accessor.pm 2013-08-02 22:19:21.000000000 +0100 +++ Accessor.pm 2013-08-19 12:07:57.000000000 +0100 @@ -5,7 +5,7 @@ use base qw(Moo::Object); use Sub::Quote; use B 'perlstring'; -use Scalar::Util 'blessed'; +use Scalar::Util qw( blessed refaddr ); use overload (); use Module::Runtime qw(use_module); BEGIN { @@ -21,12 +21,13 @@ sub _SIGDIE { our ($CurrentAttribute, $OrigSigDie); - $OrigSigDie ||= sub { die $_[0] }; + my $next = sub { die $_[0] }; + $next = $OrigSigDie if $OrigSigDie && refaddr($OrigSigDie)!=refaddr(\&_SIGDIE); - return $OrigSigDie->(@_) if ref($_[0]); + return $next->(@_) if ref($_[0]); my $attr_desc = _attr_desc(@$CurrentAttribute{qw(name init_arg)}); - $OrigSigDie->("$CurrentAttribute->{step} for $attr_desc failed: $_[0]"); + $next->("$CurrentAttribute->{step} for $attr_desc failed: $_[0]"); } sub _die_overwrite
Subject: accessor-deep-recursion.t
# RT#87575 use strictures 1; use Test::More; use Test::Fatal; { package Accessor::Test; use Moo; has 'attr1' => is => 'lazy', isa => sub { die 'Failed type constraint' }, coerce => sub { $_[ 0 ] }, default => 'dummy'; has 'attr2' => is => 'lazy', isa => sub { 1 }, coerce => sub { $_[ 0 ] }, default => sub { $_[ 0 ]->attr1 }; } my $obj = Accessor::Test->new(); like exception { $obj->attr2 }, qr{ Failed \s+ type \s+ constraint }mx, 'Deep recursion'; done_testing;
Whoops, forgot to update this ticket. I already have a branch with a test and fix in the Moo repo, which I'll merge before the next release.
Fixed in Moo 1.003001.