Luna Luna - 1 month ago 14
Perl Question

Prototype mismatch: sub main::any: none vs (&@) at Exporter.pm

use Dancer2;
use List::Util qw(any);

sub use_any_subroutine {

foreach my $foo (@$foo_array) {
next unless any { $_ == $foo->id } @hello_world;
}
return;
}


there is a conflict with using List::Util and throwing a warning

Prototype mismatch: sub main::any: none vs (&@) at Exporter.pm(...).

i found a solution that is we can use
List::Util::any
instead of importing it before use,but i want to import it once,so how to avoid this warning

Thanks very much for comments.

Answer

Both Dancer2 and List::MoreUtils export an any function into your namespace.

For Dancer2, it's part of its DSL and is used as a route definition that matches any HTTP verb on incoming requests.

Defines a route for multiple HTTP methods at once

The List::MoreUtils one is like a grep instead.

Returns a true value if any item in LIST meets the criterion given through BLOCK.

The warning you are seeing is because you have imported the Dancer2 one first, so Perl learned about the prototype of that one. Then you imported the one from List::MoreUtils, which overwrote &main::any in your namespace main::, but the prototype is still there.

Since you cannot tell Dancer2 not to import its any, you will have to resort to require List::MoreUtils and using List::MoreUtils::any.

use Dancer2;
require List::MoreUtils;

get '/' => sub {
    my @foo = ( 1, 2, 3 );
    return List::MoreUtils::any( sub { $_ == 2 }, @foo);
};

dance;

When you curl localhost:3000/, it will not complain. Note how I needed to use parenthesis and anonymous subroutine with a comma afterwards, instead of just a BLOCK and no comma. That's because Perl gets confused thinking the fully qualified function name is supposed to be used as object oriented syntax. It tries to call the method List::MoreUtils::any on the first argument, which is the BLOCK, but which it assumes to be a blessed reference, and that breaks.