Skip Menu |

This queue is for tickets about the Moo CPAN distribution.

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

People
Owner: Nobody in particular
Requestors: MMAURICE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.000007
Fixed in: 1.002000



Subject: meta trouble
I was trying to call 'meta->calculate_all_roles' on all of Dancer2's objects which can meta. I get two error messages which I don't really understand. I am guessing here that both errors have something to do with Moo's FakeMetaClass.pm Below are traces with Moo 1.000007 and current Moose. I have looked at the two respective Dancer classes (Dancer::Core::Role::Config and Dancer::Core::Request at https://github.com/PerlDancer/Dancer2/tree/master/lib/Dancer/Core). They look ok to me. Any ideas? Thanks! Much appreciated. Use of uninitialized value $type_constraint_name in substitution (s///) at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 294, <DATA> line 998. Moose::Util::TypeConstraints::normalize_type_constraint_name(undef) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 271 Moose::Util::TypeConstraints::find_or_parse_type_constraint(undef) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 260 Moose::Util::TypeConstraints::find_or_create_isa_type_constraint(undef, 'HASH(0x80ee8d20)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin- threads-64int/Moose/Meta/Attribute.pm line 369 Moose::Meta::Attribute::_process_isa_option('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 296 Moose::Meta::Attribute::_process_options('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 88 Moose::Meta::Attribute::new('Moose::Meta::Attribute', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'isa', undef, 'builder', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 114 Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribut e', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 704 Moose::Meta::Class::_process_new_attribute('Moose::Meta::Class=HASH(0x80 e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 697 Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x80e09b 38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 566 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x80e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose.pm line 124 Moo::HandleMoose::inject_real_metaclass_for('Dancer::Core::App') called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose/FakeMetaClass.pm line 8 Moo::HandleMoose::FakeMetaClass::AUTOLOAD('Moo::HandleMoose::FakeMetaCla ss=HASH(0x801d9998)') called at t/meta.t line 38 main::wanted() called at /usr/lib/perl5/5.14/File/Find.pm line 781 File::Find::_find_dir('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib', 1) called at /usr/lib/perl5/5.14/File/Find.pm line 569 File::Find::_find_opt('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at /usr/lib/perl5/5.14/File/Find.pm line 1070 File::Find::find('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at t/meta.t line 18 Use of uninitialized value $_[0] in pattern match (m//) at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 695, <DATA> line 998. Moose::Util::TypeConstraints::_detect_type_constraint_union(undef) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 274 Moose::Util::TypeConstraints::find_or_parse_type_constraint(undef) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 260 Moose::Util::TypeConstraints::find_or_create_isa_type_constraint(undef, 'HASH(0x80ee8d20)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin- threads-64int/Moose/Meta/Attribute.pm line 369 Moose::Meta::Attribute::_process_isa_option('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 296 Moose::Meta::Attribute::_process_options('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 88 Moose::Meta::Attribute::new('Moose::Meta::Attribute', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'isa', undef, 'builder', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 114 Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribut e', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 704 Moose::Meta::Class::_process_new_attribute('Moose::Meta::Class=HASH(0x80 e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 697 Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x80e09b 38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 566 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x80e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose.pm line 124 Moo::HandleMoose::inject_real_metaclass_for('Dancer::Core::App') called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose/FakeMetaClass.pm line 8 Moo::HandleMoose::FakeMetaClass::AUTOLOAD('Moo::HandleMoose::FakeMetaCla ss=HASH(0x801d9998)') called at t/meta.t line 38 main::wanted() called at /usr/lib/perl5/5.14/File/Find.pm line 781 File::Find::_find_dir('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib', 1) called at /usr/lib/perl5/5.14/File/Find.pm line 569 File::Find::_find_opt('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at /usr/lib/perl5/5.14/File/Find.pm line 1070 File::Find::find('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at t/meta.t line 18 Use of uninitialized value $_[0] in pattern match (m//) at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 674, <DATA> line 998. Moose::Util::TypeConstraints::_detect_parameterized_type_constraint(unde f) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 274 Moose::Util::TypeConstraints::find_or_parse_type_constraint(undef) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Util/TypeConstraints.pm line 260 Moose::Util::TypeConstraints::find_or_create_isa_type_constraint(undef, 'HASH(0x80ee8d20)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin- threads-64int/Moose/Meta/Attribute.pm line 369 Moose::Meta::Attribute::_process_isa_option('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 296 Moose::Meta::Attribute::_process_options('Moose::Meta::Attribute', 'config_location', 'HASH(0x80c30c80)') called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 88 Moose::Meta::Attribute::new('Moose::Meta::Attribute', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'isa', undef, 'builder', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Attribute.pm line 114 Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribut e', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 704 Moose::Meta::Class::_process_new_attribute('Moose::Meta::Class=HASH(0x80 e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 697 Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x80e09b 38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads- 64int/Moose/Meta/Class.pm line 566 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x80e09b38)', 'config_location', 'reader', 'config_location', 'init_arg', 'config_location', 'builder', '_build_config_location', 'isa', ...) called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose.pm line 124 Moo::HandleMoose::inject_real_metaclass_for('Dancer::Core::App') called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose/FakeMetaClass.pm line 8 Moo::HandleMoose::FakeMetaClass::AUTOLOAD('Moo::HandleMoose::FakeMetaCla ss=HASH(0x801d9998)') called at t/meta.t line 38 main::wanted() called at /usr/lib/perl5/5.14/File/Find.pm line 781 File::Find::_find_dir('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib', 1) called at /usr/lib/perl5/5.14/File/Find.pm line 569 File::Find::_find_opt('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at /usr/lib/perl5/5.14/File/Find.pm line 1070 File::Find::find('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at t/meta.t line 18 Dancer::Core::Request Can't call method "coercion" on an undefined value at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose.pm line 107, <DATA> line 998. Moo::HandleMoose::inject_real_metaclass_for('Dancer::Core::Request') called at /usr/lib/perl5/site_perl/5.14/Moo/HandleMoose/FakeMetaClass.pm line 8 Moo::HandleMoose::FakeMetaClass::AUTOLOAD('Moo::HandleMoose::FakeMetaCla ss=HASH(0x81052750)') called at t/meta.t line 38 main::wanted() called at /usr/lib/perl5/5.14/File/Find.pm line 781 File::Find::_find_dir('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib', 1) called at /usr/lib/perl5/5.14/File/Find.pm line 569 File::Find::_find_opt('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at /usr/lib/perl5/5.14/File/Find.pm line 1070 File::Find::find('HASH(0x8002bea8)', '/home/maurice/projects/dancer2/t/../lib') called at t/meta.t line 18
I add my two quick and dirty test file in case you want to see what I did. The rest is a current clone from Dancer2 from github (URL see above). I posted a Dancer2 issues also on Github.
Subject: meta.t
#!perl use strict; use warnings; use Test::More; use Module::Load; use File::Find; use FindBin; use File::Spec; use Cwd 'realpath', 'getcwd'; our $dir = File::Spec->catfile(getcwd, 'lib'); use Carp; use Carp::Always; $Carp::Verbose=1; my $lib = File::Spec->catfile($FindBin::Bin, '..', 'lib'); die "lib dir not found" if (!-d $lib); find({wanted => \&wanted, no_chdir => 0}, $lib); sub wanted { return if ($File::Find::name !~ /.pm$/); #only .pm my $module = realpath($File::Find::name); #quick and dirty #print "$module\n\t"; $module =~ s{$dir}{}; $module =~ s{^\/}{}; $module =~ s{\/}{::}g; $module =~ s{\.pm}{}; #print "--->$module\n"; load $module; if (!$module->can('meta')) { print "$module can't do meta\n"; } else { print "$module?\n"; foreach ($module->meta->calculate_all_roles) { print "\t".$_->name."\n"; } } } ok(1, 'ok'); done_testing;
Subject: meta2.t
use strict; use warnings; use Test::More; use Carp; use Carp::Always; sub say; package Object; use Moo; with 'Dancer::Core::Role::Config'; 1; package main; my $o=Object->new (); say "o can meta" if $o->can('meta'); foreach ($o->meta->calculate_all_roles) { say $_->name; } ok (1,'tomorrow'); done_testing; sub say { print $_[0]."\n" }
I've not looked into this extensively yet (hopefully will do soon) but it appears that if there's an coderef entry for a type in %Moo::HandleMoose::TYPE_MAP And running that coderef returns undef in scalar context, then this problem will occur. In the "do" block on line 97 of lib/Moo/ HandleMoose.pm we need to be checking that $mapped->() returns something useful, and if it does not, then treat it as if there was no coderef found in %TYPE_MAP in the first place.
OK, this test case replicates without needing Dancer2.
Subject: moo-typeconstraint-inflation-fail.t
use strict; use warnings; use Test::More; BEGIN { package Local::Types; no thanks; use MooX::Types::MooseLike; use base 'Exporter'; MooX::Types::MooseLike::register_types( [ { name => 'Chipmonk', message => sub { "$_[0] is not a recognised chipmonk" }, test => sub { grep { $_[0] eq $_ } qw( Alvin Simon Theodore ) }, }, ], __PACKAGE__, ); }; BEGIN { package Local::Class; no thanks; use Moo; use Local::Types 'Chipmonk'; has pet => (is => 'ro', isa => Chipmonk); }; "Local::Class"->new( pet => 'Alvin' ); eval q{ package Local::Subclass; no thanks; use Moose; extends 'Local::Class'; }; "Local::Subclass"->new( pet => 'Alvin' ); pass(); done_testing();
My test case passes if the "do" block is changed to: do { exists($TYPE_MAP{$isa}) && $TYPE_MAP{$isa}->() or Moose::Meta::TypeConstraint->new( constraint => sub { eval { &$isa; 1 } } ); }
git branch "dancer-tc-inflation-rt82098" contains test case and fix.
It looks like a better option may be for Dancer2 to add a dependency on the newest version of MooX::Types::MooseLike. This offers greater control over how Moo type constraints get "inflated" into Moose type constraints. In particular, adding `inflate => 0` to a type definition will prevent MooX::Types::MooseLike from using its standard inflation technique (which is to simply assume that there already exists a Moose type constraint with the same name as the Moo type constraint), and should be sufficient to solve the particular failure reported in this ticket. Recent versions of MooX::Types::MooseLike also offer Enum and InstanceOf parameterized type constraints which may provide better ways of defining Dancer2's current DancerMethod, DancerHTTPMethod, App, Context, Cookie, DSL, etc types.
mst says that this is the fault of MooX::Types::MooseLike for returning undef in response to inflating certain type constraints. I agree, and have provided a patch for MooX::Types::MooseLike to help fix the issue at that end. But I still think we should take the belt and braces approach, and merge my git branch for this issue into Moo. All my patch does is if the coderef in %TYPE_MAP returns false, pretends like the coderef never existed in the first place, allowing Moo to fall back to its built-in type constraint inflation - i.e. the same inflation it uses for plain old isa => sub {...}.
The latest Moo release throws an error if a TYPE_MAP returns an invalid result. Any further issues with this are bug to be fixed in other modules.