2017-11-02 23 views
6

Tôi muốn tải có điều kiện gói nếu tên chương trình là tập lệnh thử nghiệm kết thúc bằng .t.Lỗi khi sử dụng nếu REGEX_COND

Tuy nhiên, tôi đang chạy vào lỗi nơi use if không thành công khi điều kiện là regex. Tôi đã thử nghiệm điều này trong Perl 5.10 và 5.16.

Sau đây là kịch bản thử nghiệm của tôi kết thúc bằng .t:

#!/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'; 

Đầu ra:

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

Tuy nhiên, cùng một tập tin có phần mở rộng .pl thất bại:

$ ./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. 

Tôi có thể ép buộc mã vào làm việc nếu tôi tăng gấp đôi bang regex hoặc thay đổi nó thành một so sánh chất nền:

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

Đầu ra:

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

Đây có phải là một lỗi được biết? Nếu vậy, phiên bản nào đã được sửa?

Trả lời

8

Đây là lỗi trong mã của bạn.

Danh sách đối số sau use MODULE ở trong, tốt, liệt kê ngữ cảnh.

m// trong ngữ cảnh danh sách trả về danh sách các chuỗi đã ghi nếu thành công (hoặc 1 nếu regex không chứa nhóm chụp) hoặc danh sách trống khi không thành công.

Như vậy:

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

tương đương với

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

(. Trận đấu thất bại, vì vậy một danh sách trống được trả lại)

, trong danh sách bối cảnh là những nhà khai thác danh sách nối, do đó, điều này cho:

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

'List::Util' là một giá trị thực sự, vì vậy điều này cuối cùng kết thúc lên bốc pairmap.pm:

use pairmap; 

Việc sửa chữa là để cho bối cảnh trận đấu vô hướng:

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

(! còn cung cấp bối cảnh vô hướng để toán hạng của nó, do đó !! có cùng tác dụng.)