Почему вывод Dumper не оценивается правильно? - PullRequest
2 голосов
/ 06 августа 2020

Я пытаюсь eval выводить Dumper для довольно простого хеш-кода, где два ключа имеют одинаковое значение (ссылка на другой ha sh):

#!/usr/bin/env perl

use strict; use warnings;
use Data::Dumper;

my $foo = { data => 1 };
my $boo = {
  x => $foo,
  y => $foo,
};

my $VAR1;
my $bar = eval( Dumper( $boo ) );

print Dumper( $boo );
print Dumper( $bar ); 

Я ожидаю $boo и $bar, чтобы иметь ту же структуру, но eval, похоже, не решает внутреннюю ссылку $VAR1->{'x'} правильно, я надеялся, что последние 2 строки напечатают одну и ту же строку:

$VAR1 = {
          'x' => {
                   'data' => 1
                 },
          'y' => $VAR1->{'x'}
        };

Но вторая имеет x или y undefined (в зависимости от того, что было указано в буквальной форме):

$VAR1 = {
          'x' => {
                   'data' => 1
                 },
          'y' => undef
        };

Я пробовал простое использование часть на do c, и это дало прекрасные результаты с гораздо более сложной структурой (no strict, пока), но я могу 'выполнить sh это с моими данными с двумя ссылками на тот же ha sh.

Что мне здесь не хватает?

1 Ответ

4 голосов
/ 06 августа 2020

Для корректного захвата ссылок внутри структуры вам необходимо установить флаг Purity (подробности см. В документации Data :: Dumper ).

$Data::Dumper::Purity = 1;

Этого недостаточно , хотя, поскольку Dumper($boo) теперь вернет

$VAR1 = {
          'y' => {
                   'data' => 1
                 },
          'x' => {}
        };
$VAR1->{'x'} = $VAR1->{'y'};

Таким образом, вы не можете просто eval эту строку, вам также нужно вернуть $VAR1 из нее.

To чтобы флаг чистоты не мешал другим частям кода, вы можете установить его локально:

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;

my $foo = { data => 1 };
my $boo = {
    x => $foo,
    y => $foo,
};

my $VAR1;
my $bar = do {
    local $Data::Dumper::Purity = 1;
    eval Dumper( $boo );
    $VAR1
};

print Dumper( $boo );
print Dumper( $bar );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...