Thursday, March 24, 2011

Is there a builtin "hash to string" in Perl?

I'm coming to learn Perl from a Python background where the following hash-to-string conversion is built in to the language:

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

Is there a builtin and/or module that has a subroutine with output along the lines of:

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

Strangely, a web search for perl "hash to string" doesn't turn up anything along the lines I'm looking for. Thanks!

From stackoverflow
  • There is the Data::Dumper module which one way to do this sort of transformation.

    Leon Timmermans : Yes, but it does prepend a `$VAR1 = ` before the string.
    Greg Hewgill : That's true, annoying but tractable.
    Leon Timmermans : Justed found the solution to that...
    j_random_hacker : Use Data::Dump instead. It's Data::Dumper done right.
  • use Data::Dumper;
    local $Data::Dumper::Terse = 1;
    my $str = Dumper({a => 1, b => 2, c => 3});
    
    Brad Gilbert : http://search.cpan.org/perldoc?Data::Dumper
  • See also JSON:

    #!/usr/bin/perl
    use warnings; use strict;
    use JSON;
    
    my $str = {a => 1, b=> 2, c => 3};
    
    print to_json($str);
    

    This produces:

    {"c":3,"a":1,"b":2}
    
  • Use Data::Dump instead of Data::Dumper. It's basically the same, except without that annoying $VAR1 = ... cruft:

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

    Produces:

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

    If you're on Windows, Data::Dump has come pre-installed with ActivePerl since version 5.8.

    Hynek -Pichi- Vychodil : Can't locate Data/Dump.pm in @INC - it is not standard library.
    Kev : On ActivePerl 5.10, build 1004, Data::Dump 1.08 came pre-installed.
    Kev : +1, I hadn't realized this module exists BTW. It lacks certain add-ons like HTML formatting, but oh well.
    j_random_hacker : Kev: Are you saying that good ol' Data::Dumper can produce HTML-formatted output? If so that's pretty cool...
  • Yet Another Swallow Solution:

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

    But use Data::Dumper instead.

    For very fancy output you can use also:

    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;
    }
    

    If you prefer some keys should be first than you can use this approach (i want type first and position second):

        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] }
                ];
        };
    

0 comments:

Post a Comment