redtux has asked for the wisdom of the Perl Monks concerning the following question:

Running through perlcritic I get the following warning, refering to the sub-routine containing the below code

Always unpack @_ first.

This refers to the line where the parent sub-outine is defined (in this case 7408 and the following is at line 7655)

However it is is triggered by the mce_loop routine. Weirdly if I dont unpack @_ the warning doesn't occur.

Any ideas?

use MCE::Loop; MCE::Loop->init( chunk_size => 1, max_workers => 10, use_threads => 0 ); my %result; MCE::Util::get_ncpu %result = mce_loop { my ($mce,$chunk_ref,$chunk_id) = @_; my %ret; for my $item (@{ $chunk_ref }) { my $ret=tags_get($item); $ret{$item->[1]}=$ret->{$item->[1]}; #say $ret{$_->[1]}; } $mce->gather(%ret); } $fileprobe; MCE::Loop->finish;

Replies are listed 'Best First'.
Re: perlcritic and MCE::Loop
by hippo (Archbishop) on Feb 18, 2021 at 13:33 UTC

    I am unable to reproduce your findings (if I have understood them correctly):

    $ cat 11128519.pl use strict; use warnings; use MCE::Loop; MCE::Loop->init ( chunk_size => 1, max_workers => 10, use_threads => 0 ); my %result; MCE::Util::get_ncpu %result = mce_loop { my ($mce, $chunk_ref, $chunk_id) = @_; my %ret; for my $item (@{$chunk_ref}) { my $ret = tags_get ($item); $ret{$item->[1]} = $ret->{$item->[1]}; #say $ret{$_->[1]}; } $mce->gather (%ret); } $fileprobe; MCE::Loop->finish; $ perlcritic 11128519.pl 11128519.pl source OK $ perlcritic -2 11128519.pl Code not contained in explicit package at line 1, column 1. Violates +encapsulation. (Severity: 4) No package-scoped "$VERSION" variable found at line 1, column 1. See +page 404 of PBP. (Severity: 2) Module does not end with "1;" at line 26, column 1. Must end with a r +ecognizable true value. (Severity: 4) $ perlcritic --version 1.125 $

    PS. Perhaps the problem lies with the code you haven't shown us (the calling code)?


    🦛

Re: perlcritic and MCE::Loop
by LanX (Saint) on Feb 18, 2021 at 13:34 UTC
    > Any ideas?

    Short guess: write

    %result = mce_loop sub {

    if you want to keep that Citric rule activated.

    Long guess: mce_loop seems to be defined with a prototype (&) which treats a following code block like a sub

    Critic doesn't see that and thinks the @_ is not at the right position.

    Inserting an explicit sub should fix that

    Disclaimer: I'm neither a user of critic nor mce, and can't test.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    update

    It's unlikely that Critic is always doing that, because such prototype stuff is not uncommon. The full answer is in your environnement.

      For info doing this

      %result = mce_loop sub {

      Results in a syntax error

      However wrapping the the whole thing in a sub removes the error, will have to see if it breaks the code.ie

      %result = mce_loop {sub { my ($mce,$chunk_ref,$chunk_id) = @_; my %ret; for my $item (@{ $chunk_ref }) { my $ret=tags_get($item); $ret{$item->[1]}=$ret->{$item->[1]}; #say $ret{$_->[1]}; } $mce->gather(%ret); } } $fileprobe;

      thanks

        did you separate the arguments behind the block with a comma after introducing "sub"?

        DB<25> sub run (&@) { my $code =shift; $code->(@_) } DB<26> *mce_loop = \&run DB<27> mce_loop {print "code @_"} 1,2,3 # no comma needed code 1 2 3 DB<28> mce_loop sub {print "code @_"}, 1,2,3 # comma needed code 1 2 3 DB<29> mce_loop sub {print "code @_"} 1,2,3 # syntax error Number found where operator expected at (eval 38) ...

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        > '%result = mce_loop sub {'

        > Results in a syntax error

        this shouldn't be, the problem must be somewhere in your code.

        I looked into the code of MCE::Loop and it works like I guessed.

        That's what's essentially happening in the import

        DB<8> sub run (&@) {} DB<9> *mce_loop = \&run DB<10> mce_loop {print "code"} DB<11> mce_loop sub {print "code"} DB<12> mce_loop sub {print "code"},@_ DB<13> mce_loop 1 Type of arg 1 to main::run must be block or sub {} (not constant item) + at

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery