Tôi bắt đầu nhận thấy điều gì đó kỳ lạ về số Scope::Guard
.DESTROY được gọi theo trình tự không mong muốn
- Nếu tôi undef một biến
$guard
như báo cáo kết quả cuối cùng trong một tiểu, tiểu của bảo vệ được gọi muộn hơn tôi mong đợi. - Nếu tôi không hoàn tác, hoặc nếu tôi làm điều gì đó (mọi thứ) sau
undef $guard
, nó sẽ được gọi khi tài liệu tham khảo nằm ngoài phạm vi như được ghi lại. Tôi tự hỏi tại sao.
Mã này cũng được tìm thấy here
my $sClass = 'SGuard';
# Uncomment to use Scope::Guard instead:
# use Scope::Guard; $sClass = 'Scope::Guard';
package SGuard;
sub new {
my ($class, $sub) = @_;
return bless { sub => $sub }, $class;
}
sub DESTROY {
my ($self) = @_;
$self->{sub}->();
}
package main;
sub mySub {
my $mySubGuard = $sClass->new(sub {
print "shouldDestroyFirst\n"
});
# Do something - any no-op will do.
undef;
# Comment out this line and it works
undef $mySubGuard;
# Or uncomment the next undef line and it works. Any statement(s) or
# no-ops will do but we test the return value of mySub to make sure it
# doesn't return a reference, so undef...
# undef;
}
{
my $scopeGuard = $sClass->new(sub {
print "shouldDestroyLast\n"
});
# Check that mySub returns undef to ensure the reference *did* go out
# of scope
printf "mySub returned a %sdefined value\n", defined mySub() ? "" : "un";
}
print "done\n";
Trong đoạn code tôi đã thực hiện Scope::Guard
(SGuard
trên) chỉ để làm ví dụ của riêng tôi kém của con người như đơn giản càng tốt. Bạn cũng có thể sử dụng Scope::Guard
và nhận được kết quả chính xác giống như bất ngờ tối thiểu với tôi.
tôi hy vọng rằng $mySubGuard
bên mySub()
nên bị hủy diệt đầu tiên và $scopeGuard
trong phạm vi mà các cuộc gọi mySub()
nên bị phá hủy ngoái. Và do đó, có được sản lượng như:
shouldDestroyFirst
mySub returned a undefined value
shouldDestroyLast
done
Tôi nhận được sản lượng trên nếu tôi sử dụng undef $mySubGuard
dòng trong mySub. Nếu tôi không sử dụng undef $mySubGuard
dòng trong mySub, tôi nhận được bên dưới đầu ra:
mySub returned a undefined value
shouldDestroyLast
shouldDestroyFirst
done
Vì vậy, nó trông giống như $mySubGuard
từ mySub()
bị phá hủy sau biến địa phương để các phạm vi bên ngoài bị phá hủy.
Tại sao hành vi khác nhau chỉ vì tôi hoàn tác biến số sắp sửa rời khỏi ngoài phạm vi? Và tại sao nó quan trọng cho dù một cái gì đó được thực hiện sau đó?