perl – DESTROY以意想不到的顺序调用
我开始注意到
Scope::Guard 的奇怪之处.
>如果我将一个$guard变量取消作为sub中的最后一个语句,那么后卫的子变量就会得到 该代码也可以在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 "shouldDestroyFirstn" }); # 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 "shouldDestroyLastn" }); # Check that mySub returns undef to ensure the reference *did* go out # of scope printf "mySub returned a %sdefined valuen",defined mySub() ? "" : "un"; } print "donen"; 我在代码中创造了自己的穷人 我期待mySub()中的$mySubGuard应该首先销毁 shouldDestroyFirst mySub returned a undefined value shouldDestroyLast done 如果我在mySub中使用undef $mySubGuard行,我会得到以上输出. mySub returned a undefined value shouldDestroyLast shouldDestroyFirst done 所以,看起来mySub()的$mySubGuard被破坏了 为什么行为不同只是因为我取消了即将发生的变量 解决方法
它看起来像是某种优化.如果你取消变量并且之后不使用它,它会被放入某种队列以检查魔法或其他东西.但是,如果你之后做了什么,那么它就会成为DESTROY.
此外,可能存在一个错误,因为你在说“返回上下文”中没有它,所以有一个正在检查某个变量的变量的副本.也许Perl保留了一个引用,它随后会清理并调用范围的结束. 您还会注意到,在取消防守后,任何其他声明都会导致预期的行为.包括PBP建议结束所有潜艇的返回.达米安的一个显而易见的原因是它避免了意想不到的副作用. 问题解决了:就像取消防守一样容易,你可以直接运行它的处理程序.不要将undef guards作为sub的最后一个(隐式返回)语句.有理由明确地将undef守卫(例如你想要运行他们的处理程序)进行进一步处理. 这是令人困惑和意外的,但绝对不会在完成或标准化的代码中出现. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |