我想这取决于上下文。
- 在进行调用时重复使用
&func
- 它是为所有其他调用创建的
我有这段代码,在第 1004 行接到意外eval
调用:
sub save_context {
@DB::context = ( @_, (caller 2)[8..10], $@, $_ ); # line 1004
print_state "nTRAPPED IN ", "nn" if _ddd;
DB::state( 'inDB', 1 );
}
而这个堆栈跟踪:
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1419 DB::orig_frames
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1460 DB::push_frame
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1004 DB::__ANON__[/x/local/lib/perl5/Devel/DebugHooks.pm:1460]
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1004 (eval)
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1251 DB::save_context
DB /x/local/lib/perl5/Devel/DebugHooks.pm 1288 DB::DB_my 1
MyApp::Controller::User /x/lib/MyApp/Controller/User.pm 41 DB::DB 1
Mojolicious /x/local/lib/perl5/Mojolicious.pm 133 MyApp::Controller::User::list
Mojolicious::Plugins /x/local/lib/perl5/Mojolicious/Plugins.pm 15 Mojolicious::__ANON__[/x/local/lib/perl5/Mojolicious.pm:133]
...
从我的日志文件中,我可以看到DBIx::Class::DESTROY
sub 被调用:
DB::sub DB::state: l:1 d:0 s:5 t:0 /x/local/lib/perl5/Devel/DebugHooks.pm:1004 --> DBIx::Class::DESTROY
为什么推迟对象销毁?我想这在某种程度上与@_
有关
任何建议都值得赞赏,因为这里可能会触发对象销毁
在没有参数列表的&func
调用中,不仅重用@_
元素,还重用整个@_
。
sub main {
print "main: @_ is ", @_, "n";
func(@_); # Values from @_ are copied into new @_. @_ after call: 1 2 3
&func; # Origin @_ is passed down. So @_ after call: 2 3
}
sub func {
print "func: @_ is ", @_, "n";
shift @_; # Here @_ is modified. Pay attention what values @_ left after call
}
main(1,2,3); # @_ will be initialized by: 1 2 3
典型输出:
main: @_ is ARRAY(0xfc5958)
@_ initial: 1 2 3
func: @_ is ARRAY(0xfc5a00)
@_ after func(): 1 2 3
func: @_ is ARRAY(0xfc5958)
@_ after &func: 2 3
从main
到&func
调用,@_
不会以任何方式本地化、复制或更改。从&func
呼叫更改func
内部@_
会影响调用方中的@_
,但从func()
调用更改它不会。
我找到了为什么在分配时调用DESTROY
:
- 旧
@DB::context
物品被销毁 - 其中第一项
ARRAYREF
到子例程参数LIST
- 当这个项目被销毁时,不再有指向参数的链接,它们被销毁
由于这些链接,参数在正常情况下不会被销毁。例:
{ #1
my $handle = DBI->connect(...); #2
some_sub_call( 'arg', $handle, 1, 2, ... ); #3
} #4
another_call( a => 1 ); #5
- 这是一些范围
-
$handle
应在范围结束时销毁 - 在调试器下进行此调用时,指向
@_
的链接存储在@DB::context
- 范围的结束。
$handle
没有被销毁,因为它仍然引用 - 另一个子例程调用。
@DB::context
的旧价值观被释放。所以$handle
destrucion 被推迟到这个
所以@_
是无罪的。谢谢@mob的解释