perl – 嵌套闭包和捕获的变量
发布时间:2020-12-15 23:20:58 所属栏目:大数据 来源:网络整理
导读:我有这个带有嵌套闭包的例子,它演示了内存泄漏 use v5.10;use strict;package Awesome;sub new { bless {steps = [],surprise = undef},shift;}sub say { print "awesome: ",$_[1],"n";}sub prepare { my ($self,@steps) = @_; for my $s (@steps) { push @
我有这个带有嵌套闭包的例子,它演示了内存泄漏
use v5.10; use strict; package Awesome; sub new { bless {steps => [],surprise => undef},shift; } sub say { print "awesome: ",$_[1],"n"; } sub prepare { my ($self,@steps) = @_; for my $s (@steps) { push @{$self->{steps}},sub { $self->say($s); if ($s eq 'pony') { $self->{surprise} = sub { $s; } } }; } } sub make { my $self = shift; while (my $step = shift @{$self->{steps}}) { $step->(); } if ($self->{surprise}) { printf("And you have surprise: %sn",$self->{surprise}->()); } } sub DESTROY { warn "destroying"; } package main; my $a = Awesome->new; $a->prepare('barbie','pony','flash'); $a->make(); 我的perl输出是 awesome: barbie awesome: pony awesome: flash And you have surprise: pony destroying at /tmp/t.pl line 43 during global destruction. 而这个“在全局破坏期间”意味着物体不能以正常方式被破坏,因为它有一些循环引用. 但是,唯一的循环引用是由 push @{$self->{steps}},sub { $self->say($s); 我们在第一次关闭时使用$self.然后在make()里面我们将删除这些步骤和循环引用.但看起来这个嵌套的封闭与“惊喜”会产生问题.例如,如果我们不将“pony”传递给prepare(),那么输出将如预期的那样好: awesome: barbie awesome: flash destroying at /tmp/t.pl line 43. 那么,perl中的嵌套闭包是否捕获了与已经捕获的上层闭包相同的变量,即使我们没有使用它们? 解决方法
Perl过去常常在嵌套的闭包中过度捕获,但自5.18以来它不会这样做.
$tail -n 9 a.pl # Modified to make clearer when the object is destroyed. package main; { my $a = Awesome->new; $a->prepare('barbie','flash'); $a->make(); } print "done.n"; ? $5.16.3t/bin/perl a.pl awesome: barbie awesome: pony awesome: flash And you have surprise: pony done. destroying at a.pl line 43 during global destruction. ? $5.18.2t/bin/perl a.pl awesome: barbie awesome: pony awesome: flash And you have surprise: pony destroying at a.pl line 43. done. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |