2014-04-28 11 views
8

Tôi mới làm quen với Perl và hiện đang được giao nhiệm vụ dọn dẹp và duy trì một dự án Perl lớn và khá lộn xộn. Tôi đang sử dụng perl-nhà phê bình để giúp tôi phát hiện các vấn đề trong mã (và cũng để dạy tôi thực hành tốt nhất).Làm thế nào để phát hiện mã không thể truy cập trong Perl có điều kiện mà luôn luôn đánh giá sai?

Mã hiện tại có những nơi mà trình tạo mã đã tạo mã không thể truy cập được. Ví dụ, họ đã thêm vào '& & 0' như là một cách lười biếng của ý kiến ​​trên một số các chi nhánh mã:

if ($req->param('donut') && 0) { 
    unreachable code... 
} else { 
    always branches to here... 
} 

tôi hy vọng rằng perl hay phê bình sẽ cảnh báo cho tôi về mã unreachable trong trường hợp như vậy (trong đó một có điều kiện có giá trị hằng số được đánh giá là sai), nhưng không.

Có công cụ hay đoạn mã nào tôi có thể sử dụng để phát hiện loại điều này một cách đáng tin cậy không?

Rõ ràng tôi có thể tìm kiếm cho '& & 0' trong nguồn nhưng có một số cách mà các coder có thể tạo mã unreachable ngoài phụ thêm '& & 0' để một câu lệnh if.

Trả lời

9

Sử dụng B::Deparse, bạn có thể phát hiện mã unreachable trong một số tình huống:

perl -MO=Deparse -e 'if (0 && $x) {print 1} else {print 2}' 
do { 
    print 2 
}; 
-e syntax OK 

Nó không phải dễ dàng như vậy nếu 0 không phải là điều kiện đầu tiên, mặc dù:

perl -MO=Deparse -e 'if ($x && 0) {print 1} else {print 2}' 
if ($x and 0) { 
    print 1; 
} 
else { 
    print 2; 
} 
-e syntax OK 

Tại sao nó khác nhau? Vâng, nếu 0 đến cuối cùng, tất cả các điều kiện trước khi nó phải được kiểm tra. Chúng có thể có tác dụng phụ mà vẫn sẽ xảy ra. Ngoài ra, && buộc bối cảnh vô hướng, do đó, nó có thể thay đổi hành vi của mã được gọi khi đánh giá điều kiện.

Điều này không giải thích tại sao chính khối đó không được biên soạn, xin lỗi. Tôi đoán là nó có vẻ quá phức tạp.

+0

+1 để thông báo cho tôi về B :: Deparse.Mặc dù tác dụng phụ của phần đầu tiên của điều kiện là rõ ràng đối với tôi (có nghĩa là biểu thức điều kiện tự nó không thể được biên dịch đi), tôi đã không nhận ra về sự thay đổi của bối cảnh được giới thiệu bởi phần thứ hai của điều kiện . –

5

Theo câu trả lời của Choroba, B :: Deparse sẽ có thể cho bạn thấy những trường hợp mã rõ ràng là không thể truy cập được mà trình biên dịch Perl tối ưu hóa nó đi. Nhưng, trong trường hợp chung nó không thể phát hiện. Các mã sau đây bao gồm một khối có hiệu quả không thể truy cập.

use 5.006; 

if ($] < 5) { ... } 

$] là một biến mà trả về phiên bản hiện đang chạy của Perl, được đảm bảo có ít nhất 5,006 bởi dòng use. Nhưng bạn cần một số kỹ thuật khá thông minh để tìm ra bằng cách sử dụng phân tích tĩnh của mã nguồn. (Ngoài một điều, mặc dù một điều không bình thường để làm, có thể thay đổi giá trị của $] tại thời gian chạy - xem Acme::Futuristic::Perl - trong trường hợp đó mã sẽ trở nên có thể truy cập.)

Nếu bạn có một bộ kiểm tra phong nha cho mã của bạn, Devel::Cover có thể hữu ích. Bạn đặt biến môi trường PERL5OPT thành -MDevel::Cover, sau đó chạy bộ thử nghiệm của bạn (lưu ý rằng nó sẽ chạy chậm hơn một chút so với bình thường), sau đó chạy lệnh cover để tạo báo cáo HTML đẹp. Báo cáo này sẽ làm nổi bật những người đăng ký nào không được thực hiện, chi nhánh nào chưa bao giờ được sử dụng, v.v.

Các vấn đề liên quan