2013-07-03 27 views
5

Tài liệu có vẻ thưa thớt về các tuyên bố when bên ngoài các khối given. Người ta nói rằng when có thể được sử dụng khi một 'chủ đề' đã được thiết lập, nhưng khi chính xác là một chủ đề được coi là thiết lập? Hãy xem xét những trường hợp này:Các điều kiện mà theo đó ai có thể sử dụng câu lệnh 'when' trong Perl 5?

for (@arr) { 
    when { } 
} 

Có vẻ đây là mặc định, trường hợp cơ bản, nhưng tôi không thể nhận được thậm chí làm việc này trên perl tôi 5.14.2 - $ perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' in gì cả. Tôi đang làm gì sai? Hóa ra đây chỉ là một vấn đề trích dẫn khác.

for my $elem (@arr) { 
    when { } 
} 

Điều này có hiệu quả không? Sẽ $ elem tự động trở thành chủ đề cho when để sử dụng?

for (@arr) { 
    $_ = some_expression($_); 
    when { } 
} 

Điều này có hiệu quả không? Chủ đề có thể được đặt trong vòng lặp không?

Ngoài ra, có sự khác biệt nào khi mỗi phân đoạn mã trên sử dụng foreach thay vì for?

Về cơ bản, tôi không rõ ràng về chủ đề của chủ đề, vì vậy hãy khai sáng cho tôi.

Trả lời

7

Đó là lỗi xây dựng lệnh trình bao.

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }' 

nên

perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print '\''boom'\''} }' 

Chúng tôi có thể chuyển sang dấu ngoặc kép để đơn giản hóa

perl -Mfeature=switch -le'foreach (qw(a b c)) { when (/a/) {print "boom"} }' 

Và chúng ta có thể đơn giản hóa hơn nữa

perl -E'for (qw(a b c)) { when (/a/) { say "boom" } }' 

Từ khóa forforeach là một và giống với Perl.

Lưu ý rằng 5,18 đánh dấu givenwhen là thử nghiệm. Nó sẽ không biến mất, nhưng nó sẽ thay đổi. Tôi giải thích những gì đang diễn ra trên here.


Không, when không sử dụng $elem; nó luôn sử dụng $_.


Có, bạn có thể thay đổi $_ bên trong for hoặc given nếu bạn muốn. Lưu ý rằng các vòng lặp foreach bỏ qua chủ đề của chúng đối với phần tử đang được truy cập, vì vậy việc thay đổi một thành phần khác sẽ thay đổi.

my @x = qw(abc def); 
for (@x) { $_ = uc($_); } 
say @x; # ABCDEF 
+0

Tôi luôn đi sai với dấu ngoặc kép, cảm ơn. Cảm ơn bạn đã liên kết đến câu trả lời khác của bạn, điều đó và các liên kết từ đó đã giúp hiểu trạng thái tốt hơn. Tôi có một trường hợp lạ với cái này: 'perl -E '@arr = qw (a b c); foreach $ x (@arr) {$ _ = $ x; $ _ ++; khi (/ b /) {print $ x}} '' Nó in như mong đợi, nhưng sau đó dường như chết với lỗi" Không thể sử dụng khi() bên ngoài một topicalizer tại -e dòng 1. ". Cùng một mã chạy mà không có lỗi (nhưng in không có gì) nếu tôi loại bỏ hai dòng với $ _. Bạn có thể giải thích những gì đang xảy ra ở đây? – sundar

+0

@ sundar, Vấn đề không phải là sự lựa chọn của dấu ngoặc kép. Vấn đề là bạn đã không trốn thoát chúng đúng cách. Xem cập nhật. – ikegami

+0

cú pháp này để thoát 'là mới và hữu ích cho tôi, cảm ơn. liên quan đến việc chủ đề hóa, đó là lý do tại sao tôi đã đề cập rằng "cùng một mã chạy mà không có lỗi nếu tôi xóa hai dòng với $ _". Dường như bất kỳ vòng lặp foreach foreach nào cũng được coi là một bộ chỉnh sửa, ngay cả đối với các SOMETHING (...), nhưng gán cho $ _ bên trong vòng lặp messes lên bằng cách nào đó. – sundar

2

Ikegami đã phát hiện vấn đề thực tế của bạn. Về các câu hỏi khác:

Hai công cụ chuyên đề là for/foreachgiven. Các cấu trúc khác được đặt $_ (biến chủ đề), không được coi là đề tài (ví dụ:map hoặc grep).

Nếu bạn chạy vòng lặp foreach với biến vòng lặp rõ ràng, vòng lặp không được coi là trình xử lý hàng đầu. Do đó,

for my $x (1..3) { 
    local $_ = $x; 
    say when 2; 
} 

sẽ làm việc cho phiên đầu tiên, nhưng sau đó chết (Can không "khi" bên ngoài một topicalizer) khi when là đã thoát.

Các given khác ở chỗ nó không bản địa hóa $_, nhưng cung cấp cho một từ vựng $_. Tức là, given (@a) { foo; } cũng tương tự như { my $_ = \@a; foo; } (Tôi nghĩ rằng điều này có thể được sửa).

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