Использование eval
бесполезно, и вы не проверяете результат, но у меня есть ощущение, что вы пытаетесь понять, что на самом деле не имеет ничего общего с eval
, но когда переменные освобождены.
Perl использует подсчет ссылок, чтобы знать, когда безопасно освобождать переменную. Переменная освобождается, как только на нее ничего не ссылается. В дополнение к ссылкам на лексические (my
) переменные также ссылается область, в которой они созданы, а на переменные пакета также ссылается пакет, в котором они находятся.
При "нормальных" обстоятельствах переменная будет уничтожена при выходе из области видимости, поскольку будет удалена единственная ссылка на нее *. Области видимости создаются многими вещами, включая фигурные скобки и eval
. Вот пример:
use feature qw( say );
{ package D; DESTROY { say "Destroyed $_[0]"; } }
{
my $x = bless({}, 'D'); # $x's refcnt is 1.
say "Before scope exit";
} # $x's refcnt drops to 0, so it's freed.
say "After scope exit";
Выход:
Before scope exit
Destroyed D=HASH(0x8eff768)
After scope exit
А что если вы сохранили ссылку на $x
вне области, в которой находится $x
?
use feature qw( say );
{ package D; DESTROY { say "Destroyed $_[0]"; } }
my $ref;
{
my $x = bless({}, 'D'); # $x's refcnt is 1.
$ref = \$x; # $x's refcnt is 2.
say "Before scope exit";
} # $x's refcnt drops to 1, so it's not freed.
say "After scope exit";
$ref = undef; # $x's refcnt drops to 0, so it's freed.
say "After clearing reference";
Выход:
Before scope exit
After scope exit
Destroyed D=HASH(0x8cc4768)
After clearing reference
В вашем коде возвращенная ссылка на @a
поддерживает @a
в действии даже после выхода из созданной области. Это можно проверить, напечатав $ttt
, а затем @$ttt
.
ARRAY(0x99464b8)
1 2
Если вы вводите блок несколько раз, вы получаете ссылки на разные переменные, потому что my
выделяет новую переменную каждый раз *. Сравнить
my @a;
for (1..2) {
my $x = $_;
push @a, \$x;
}
say $a[0]; # 1
с
my @a;
my $x;
for (1..2) {
$x = $_;
push @a, \$x;
}
say $a[0]; # 2
* & mdash; Реализация отличается от этого объяснения, но это оптимизация, которая не предполагает видимых побочных эффектов.