Tôi thấy mã này trong câu trả lời cho một bài đăng khác: Why would I use Perl anonymous subroutines instead of a named one?, nhưng không thể hiểu chính xác những gì đang xảy ra, vì vậy tôi muốn tự chạy nó.Các biến được chia sẻ trong ngữ cảnh của các chương trình con với các chương trình con ẩn danh
sub outer
{
my $a = 123;
sub inner
{
print $a, "\n"; #line 15 (for your reference, all other comments are the OP's)
}
# At this point, $a is 123, so this call should always print 123, right?
inner();
$a = 456;
}
outer(); # prints 123
outer(); # prints 456! Surprise!
Trong ví dụ trên, tôi nhận được một cảnh báo: "Biến $ a sẽ không ở lại chia sẻ tại dòng 15. Rõ ràng, đây là lý do tại sao sản lượng là 'bất ngờ', nhưng tôi vẫn không thực sự hiểu những gì đang xảy ra ở đây.
sub outer2
{
my $a = 123;
my $inner = sub
{
print $a, "\n";
};
# At this point, $a is 123, and since the anonymous subrotine
# whose reference is stored in $inner closes over $a in the
# "expected" way...
$inner->();
$a = 456;
}
# ...we see the "expected" results
outer2(); # prints 123
outer2(); # prints 123
trong bối cảnh đó, tôi không hiểu những gì đang xảy ra trong ví dụ này một trong hai. Có thể ai đó xin giải thích?
Cảm ơn trước.
“Phân tích” có lẽ là từ sai ở đây, nhưng “biên soạn” dường như hơi sai quá: IIRC, cho đóng cửa các mã được biên dịch chỉ được kết hợp với một môi trường/phạm vi mới, dẫn đến một CV mới, trong khi các tên miền được đặt tên không bao giờ phục hồi lại một phạm vi mới (không có định nghĩa lại). – amon
Cảm ơn rất nhiều, điều đó rất hữu ích! –