2009-02-20 33 views
6

Trong Perl, người ta thường có thể tránh sử dụng các khối điều khiển, như thế này:biểu foreach ngắn gọn trong một dòng

print "$_\n" foreach(@files); 

thay vì:

foreach(@files){ 
    print "$_\n"; 
} 

làm việc như thế cú pháp này trong những điều sau đây, nhiều trường hợp phức tạp:

die("Not a file: $_") unless -f $_ foreach(@files); 

Nó mang lại cho tôi một lỗi cú pháp. Tôi không cố gắng viết mã obfuscated, nó chỉ là một phần không quan trọng trong chương trình, và vì vậy tôi muốn thể hiện nó một cách ngắn gọn nhất có thể.

TRẢ LỜI tóm tắt:

tôi có thể chấp nhận chỉ có một câu trả lời là câu trả lời được chấp nhận, nhưng tôi thích những người sau đây từ Chris và Jon tốt nhất.

một này sử dụng foreach như tôi dự định, nhưng nếu không có sự syntax error:

-f or die "Not a file: $_" foreach @files; 

Và một Sau đây là ít nhất là tốt. Tôi thích điều đó die là ở phần đầu của báo cáo kết quả bởi vì đó là những gì chú ý của người đọc nên hướng vào:

die("Not a file: $_") for grep {!-f} @files; 
+0

Tôi đồng ý rằng 'die()' là tốt nhất ở đầu dòng, nhưng trong một mạch ngắn, mạch ngắn chỉ có thể đọc được với tôi. –

+1

Bạn chỉ chơi gôn? Nếu không, tại sao nó quan trọng để có nó trên một dòng? –

Trả lời

12

Chỉ cần được Perlish (TMTOWTDI) bạn có thể sử dụng logic ngắn mạch:

-f or die "Not a file: $_" foreach @files; 

Tested trên OS X và các công trình.

Là một mặt lưu ý, -f or die trông giống như rất nhiều chung open() or die cấu trúc tôi thấy trong Perl, và vẫn còn (tôi nghĩ) cho thấy ý định của dòng (để die dưới những điều kiện nhất định).

+1

Rất gọn gàng. ++ và hooray cho Cưa quân đội Thụy Sĩ! –

+0

Tôi thích nó. Song song với mở() hoặc die() là một chút, vì mục đích của mở() thường là để mở một tập tin không chết(). Nhưng nếu bạn nghĩ rằng mục đích của mã trên là để kiểm tra sự tồn tại của một tập tin, song song là chính xác. Cuộc gọi khó khăn, nhưng tôi nghĩ tôi thích bạn hơn một lần nữa. ;-) –

7

Vâng, bạn có thể không ý định để viết mã rối loạn, nhưng tôi muốn nói rằng bạn chắc chắn là đang thử.

Có hai dòng (hoặc thậm chí là một khối trên một dòng, như Brent.Longborough đề xuất) thay vì một trong số đó quá tệ? Thành thật mà nói, đây là lý do tôi thường cố gắng sửa lỗi/chỉnh sửa mã perl của người khác, một số lượng lớn người viết trong perl dường như bị ám ảnh với việc làm hầu hết mọi thứ theo cách "thông minh" nhất có thể, thay vì làm nó theo cách dễ hiểu cho người khác đọc.

+0

+1. Tôi không bao giờ hiểu tại sao "clevver == chỉ trong một dòng" cho một số người. – innaM

+1

Tôi nghĩ rằng một số ví dụ (giống như sử dụng 'grep') là" thông minh ", nhưng không phải vì chúng chỉ là một dòng. Họ thông minh bởi vì họ chỉ là một dòng, nhưng rõ ràng cho thấy ý nghĩa. Và có vẻ tốt đẹp - lồng nhau ngoặc và dấu ngoặc trên một dòng trông xấu (theo ý kiến ​​của tôi (ngoại trừ trong Lisp (haha))). –

3

Nếu bạn không cố gắng viết mã bị xáo trộn, thì bạn không nên cố gắng viết mã như thế này. Bạn đang dùng cái gì đó nên đơn giản và làm cho nó khó hiểu.

+1

Địa ngục bị làm phiền về điều này là gì? Làm thế nào bạn sẽ viết nó? – Svante

+0

Tôi đồng ý với Harleqin - một số câu trả lời trên trang này cho thấy có nhiều cách để viết điều này là cả a) rõ ràng và b) một dòng. –

+0

Tôi đã trả lời nhận xét của anh ấy rằng "Tôi không cố gắng viết mã bị xáo trộn." Nỗ lực của anh ta đã bị làm xáo trộn như được định nghĩa bởi Webster: "để tránh né, không rõ ràng, hoặc khó hiểu". Các câu trả lời đã được gửi khi tôi đăng không rõ ràng và khó hiểu, trong khi một số ví dụ được đăng sau đó có vẻ ổn. – gpojd

11

Bạn có thể có thể sử dụng @ câu trả lời Brent.Longborough, hoặc nếu bạn thực sự muốn postfix, làm:

do { die("Not a file: $_") unless -f $_ } foreach(@files); 

Tuy nhiên, tôi đồng ý với những người khác, chỉ vì đây là "một phần không thể không quan trọng" không có nghĩa là súc tích tốt hơn. Số lượng khả năng đọc.

+0

Làm thế nào là nó không thể đọc được? Bạn muốn viết nó như thế nào? – Svante

+0

Tôi không nói là "không thể đọc được". Tuy nhiên, tôi khẳng định rằng nó là * ít * có thể đọc được để sử dụng cấu trúc điều khiển postfix bị xích. Đó là tất nhiên chủ quan. Vấn đề là OP không nói anh ta đang cố gắng tối đa hóa khả năng đọc, nhưng nó phải "súc tích" vì nó "không quan trọng". –

5

Nếu kiểm tra lỗi là điểm chính của mã này, có thể có ý nghĩa để nó có vị trí chính ở đầu dòng. Một cải tiến nhỏ sẽ được sử dụng grep:

die("Not a file: $_") for grep {!-f} @files; 

Nhưng nếu bạn có kế hoạch Looping qua các tập tin đối với một số lý do nào khác trong đó một phần của mã, nó sẽ là tốt hơn để thêm nó vào cơ thể của vòng lặp.

0

Chết tiệt, Jon vừa đánh tôi đến grep.

Nhưng tôi có một câu hỏi lớn hơn: làm thế nào là nó không quan trọng nếu bạn đang thực sự sẽ bảo lãnh nếu bạn tìm thấy một số không-tập tin trong mảng của bạn? (Trái với, nói, loại bỏ những mục đó, cảnh báo người dùng và sau đó xử lý phần còn lại của danh sách.) Tôi nghĩ rằng giết chết toàn bộ shebang là một phần hợp lý quan trọng của chương trình.

Trong mọi trường hợp, bạn không thể làm chính xác những gì bạn muốn với công cụ sửa đổi postfix vì bạn chỉ có thể có một thứ ở hai bên của chúng. Vì vậy, bạn không thể có cả số unlessforeach. Từ đỉnh bit có liên quan của perldoc perlsyn:

Bất kỳ tuyên bố đơn giản tùy chọn có thể được theo sau bởi một modifier SINGLE, ngay trước dấu chấm phẩy chấm dứt (hoặc khối kết thúc).

+0

Vâng. Nếu nó chỉ là một bản in, tôi muốn nói rằng các ký hiệu truyền thống là tốt hơn. Nhưng chết có lẽ phải là mã thông báo đầu tiên trên một dòng nếu có thể. –

-2

Bạn đã chết.

Your maintenance programmer http://www.codinghorror.com/blog/images/carny.jpg

Tôi hy vọng anh ấy không bao giờ tìm thấy bạn. Nhưng bạn nên think about him whenever you code.

+0

Trích dẫn tốt hơn, nhưng ít gây sốc hơn từ bài viết được liên kết: "Cách khác, luôn viết mã và nhận xét theo cách mà nếu ai đó có vài bậc học sinh chọn mã, họ sẽ rất thích đọc và học từ nó . " - http://c2.com/cgi/wiki?CodeForTheMaintainer –

1

Bạn đang suy nghĩ quá khó. Dưới đây là trên cùng một dòng không có những màn nhào lộn:

foreach (@files) { die("Not a file!") unless -f } 

Bạn có thể chơi xung quanh với những thứ bên trong khối golf nó xuống, nhưng loại bỏ các dấu ngoặc và niềng răng không được giúp đỡ bạn bất kỳ, và có lẽ sẽ gây nhầm lẫn cho lập trình viên tiếp theo, người phải nhìn vào nó.

Bạn có thể có điều phức tạp hơn, và đây chỉ là một ví dụ. Trong thế giới thực, nó trở nên dễ dàng hơn:

not_a_file_die_die_die(\@files); 

Sau đó, bạn di chuyển tất cả nội dung phức tạp sang chương trình con. Bí quyết thực tế là làm cho ý tưởng ý tưởngnhằm mục đích súc tích, không phải mã thực hiện ý tưởng. Cơ chế thực sự không quan trọng trong nhiều trường hợp; bạn quan tâm nhiều hơn đến kết quả. Trong những trường hợp đó, đừng đổ mồ hôi cơ học.

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