this will no longer throw an error. Reported by Mark-Jason Dominus. Fixes
RT 69988. (Dave Rolsky)
- [BUG FIXES]
-
- * A subtype of a union type did not return the right results when you called
- ->is_subtype_of or ->is_a_type_of on it. This has been fixed. RT
- #70322. (Dave Rolsky)
+ * The error generated by unfulfilled method requirements during role
+ composition now mentions how to work around imported methods not being
+ recognized. Reported by Michael Schwern. Fixes RT 60583. (doy)
[OTHER]
use warnings;
use metaclass;
+use List::MoreUtils 'firstval';
use Moose::Util 'english_list';
use Scalar::Util 'weaken', 'blessed';
. "' requires the $noun $list "
. "to be implemented by '"
. $class->name . q{'};
+
+ if (my $meth = firstval { $class->name->can($_) } @missing) {
+ $error .= ". If you imported functions intending to use them as "
+ . "methods, you need to explicitly mark them as such, via "
+ . $class->name . "->meta->add_method($meth => \\\&$meth)";
+ }
}
$class->throw_error($error);
--- /dev/null
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+use Test::Fatal;
+use Test::Moose;
+
+BEGIN {
+ package ExportsFoo;
+ use Sub::Exporter -setup => {
+ exports => ['foo'],
+ };
+
+ sub foo { 'FOO' }
+
+ $INC{'ExportsFoo.pm'} = 1;
+}
+
+{
+ package Foo;
+ use Moose::Role;
+ requires 'foo';
+}
+
+{
+ package Bar;
+ use Moose::Role;
+ requires 'bar';
+}
+
+{
+ package Class;
+ use Moose;
+ use ExportsFoo 'foo';
+ ::like(
+ ::exception { with 'Foo' },
+ qr/^\Q'Foo' requires the method 'foo' to be implemented by 'Class'. If you imported functions intending to use them as methods, you need to explicitly mark them as such, via Class->meta->add_method(foo => \&foo)/,
+ "imported 'method' isn't seen"
+ );
+ Class->meta->add_method(foo => \&foo);
+ ::is(
+ ::exception { with 'Foo' },
+ undef,
+ "now it's a method"
+ );
+
+ ::like(
+ ::exception { with 'Bar' },
+ qr/^\Q'Bar' requires the method 'bar' to be implemented by 'Class' at/,
+ "requirement isn't imported, so don't give the extra info in the error"
+ );
+}
+
+does_ok('Class', 'Foo');
+
+done_testing;