Есть встроенный хеш для строки в Perl?

Я прихожу, чтобы изучить Perl из фона Python, где в язык встроено следующее преобразование хеш-строки:

>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> str(d)
"{'a': 1, 'c': 3, 'b': 2}"

Есть ли встроенный и/или модуль, который имеет подпрограмму с выходом по строкам:

"('a' => 1, 'b' => 2, 'c' => 3)"

Странно, веб-поиск perl "hash to string" не вызывает ничего по строкам, которые я ищу. Спасибо!

Ответы

Ответ 1

use Data::Dumper;
local $Data::Dumper::Terse = 1;
my $str = Dumper({a => 1, b => 2, c => 3});

Ответ 2

См. также JSON:

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

my $data = {a => 1, b=> 2, c => 3};

print to_json($data);

Это дает:

{"c":3,"a":1,"b":2}

Ответ 3

Существует модуль Data::Dumper, который является одним из способов сделать такое преобразование.

Ответ 4

Используйте Data:: Dump вместо Data:: Dumper. Это в основном то же самое, кроме без этого раздражающего $VAR1 = ... cruft:

use Data::Dump "pp";
print pp({a => 1, b => 2, c => 3});

Выдает:

{ a => 1, b => 2, c => 3 }

Если вы находитесь в Windows, Data:: Dump поставляется с предустановленной ActivePerl с версии 5.8.

Ответ 5

Еще одно решение для ласточек:

sub pp {
  my $h = shift();
  qq[{${\(join',',map"$_=>$h->{$_}",keys%$h)}}]
}
print pp({a => 1, b => 2, c => 3});

Вместо этого используйте Data::Dumper.

Для очень фантастического вывода вы также можете использовать:

use Data::Dumper;
use Perl::Tidy;
sub pp {
        local $Data::Dumper::Terse    = 1;
        local $Data::Dumper::Indent   = 0;
        my $source = Dumper(@_);
        my $result;
        Perl::Tidy::perltidy(
                source      => \$source,
                destination => \$result,
                argv        => [qw(-pbp -nst)]
        );
        return $result;
}

Если вы предпочитаете, что некоторые ключи должны быть первыми, чем вы можете использовать этот подход (сначала я хочу type и position второй):

    local $Data::Dumper::Sortkeys = sub {
            [   sort {
                            if    ( $b eq 'type' )     {1}
                            elsif ( $a eq 'type' )     {-1}
                            elsif ( $b eq 'position' ) {1}
                            elsif ( $a eq 'position' ) {-1}
                            else                       { $a cmp $b }
                            } keys %{ $_[0] }
            ];
    };

Ответ 6

Некоторые из вышеперечисленных решений имеют проблему, если у вас есть потенциал для многоуровневых структур.

В частности, этот флаг:

$Data::Dumper::Terse    = 1;

Как указано на странице perldoc для Data:: Dumper, флаг "terse" может генерировать вывод, не содержащий perl.

Если вы, возможно, собираетесь иметь многоуровневые структуры, правильная вещь должна была бы использовать:

$Data::Dumper::Indent = 0;

который гарантированно является perl-анализируемым методом eval, что делает очень простой способ сделать сериализацию открытым текстом...