2017-11-02 3 views
6

Ich möchte ein Paket bedingungsabhängig laden, wenn der Programmname ein Testskript ist, das auf .t endet.Fehler bei der Verwendung von REGEX_COND

Allerdings renne ich in einen Fehler, wo use if schlägt fehl, wenn die Bedingung eine Regex ist. Ich habe das in Perl 5.10 und 5.16 getestet.

Das folgende ist mein Testskript in .t endet:

#!/usr/bin/env perl 

use v5.10; 

BEGIN { say "\$0 is '$0'" } 

use if $0 =~ /\.t\z/, 'List::Util', ('pairmap'); 

say "List::Util is " . ($INC{"List/Util.pm"} ? '' : 'NOT ') . 'included'; 

Ausgänge:

$ ./test.t 
$0 is './test.t' 
List::Util is included 

jedoch die gleiche Datei mit einer Erweiterung .pl fehlschlägt:

$ ./test.pl 
$0 is './test.pl' 
Can't locate pairmap.pm in @INC (@INC contains: /usr/lib64/perl5/5.10.0 /usr/lib64/perl5 /usr/local/share/perl5/x86_64-linux-thread-multi /usr/local/share/perl5 /usr/local/lib64/perl5 /usr/share/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/share/perl5/if.pm line 13. 
BEGIN failed--compilation aborted at ./test.pl line 7. 

Ich kann den Code zum Arbeiten zwingen, wenn ich die Regex doppelt bange oder in einen Subtr-Vergleich umwandle:

use if !!($0 =~ /\.t\z/), 'List::Util', ('pairmap'); 
use if substr($0, -2) eq '.t', 'List::Util', ('pairmap'); 

Ausgänge:

$ ./test.pl 
$0 is './test.pl' 
List::Util is NOT included 

Ist dies ein bekannter Fehler? Wenn ja, in welcher Version wurde es behoben?

Antwort

8

Dies ist ein Fehler in Ihrem Code.

Die Argumentliste nach use MODULE ist in, nun, Listenkontext.

m// im Listenkontext gibt bei Erfolg eine Liste der erfassten Zeichenfolgen zurück (oder 1, wenn die Regex keine einfangenden Gruppen enthält) oder die leere Liste bei Fehler.

So:

use if "test.pl" =~ /\.t\z/, 'List::Util', ('pairmap'); 

entspricht

use if(), 'List::Util', ('pairmap'); 

(. Das Spiel ist fehlgeschlagen, so dass eine leere Liste zurückgegeben wird)

, in Listenkontext ist die Liste Verkettungsoperator, so ergibt dies:

use if 'List::Util', 'pairmap'; 

'List::Util' ist ein wahrer Wert, so dass diese endet schließlich nach oben Laden pairmap.pm:

use pairmap; 

Das Update ist das Spiel Skalarkontext zu geben:

use if scalar($0 =~ /\.t\z/), 'List::Util', 'pairmap'; 

(! auch Skalarkontext seiner Operanden liefert, so hat !! den gleichen Effekt.)

Verwandte Themen