How can I print the contents of a hash in Perl?

365,099

Solution 1

Data::Dumper is your friend.

use Data::Dumper;
my %hash = ('abc' => 123, 'def' => [4,5,6]);
print Dumper(\%hash);

will output

$VAR1 = {
          'def' => [
                     4,
                     5,
                     6
                   ],
          'abc' => 123
        };

Solution 2

Easy:

print "$_ $h{$_}\n" for (keys %h);

Elegant, but actually 30% slower (!):

while (my ($k,$v)=each %h){print "$k $v\n"}

Solution 3

Here how you can print without using Data::Dumper

print "@{[%hash]}";

Solution 4

For debugging purposes I will often use YAML.

use strict;
use warnings;

use YAML;

my %variable = ('abc' => 123, 'def' => [4,5,6]);

print "# %variable\n", Dump \%variable;

Results in:

# %variable
---
abc: 123
def:
  - 4
  - 5
  - 6

Other times I will use Data::Dump. You don't need to set as many variables to get it to output it in a nice format than you do for Data::Dumper.

use Data::Dump = 'dump';

print dump(\%variable), "\n";
{ abc => 123, def => [4, 5, 6] }

More recently I have been using Data::Printer for debugging.

use Data::Printer;
p %variable;
{
    abc   123,
    def   [
        [0] 4,
        [1] 5,
        [2] 6
    ]
}

( Result can be much more colorful on a terminal )

Unlike the other examples I have shown here, this one is designed explicitly to be for display purposes only. Which shows up more easily if you dump out the structure of a tied variable or that of an object.

use strict;
use warnings;

use MTie::Hash;
use Data::Printer;

my $h = tie my %h, "Tie::StdHash";
@h{'a'..'d'}='A'..'D';
p %h;
print "\n";
p $h;
{
    a   "A",
    b   "B",
    c   "C",
    d   "D"
} (tied to Tie::StdHash)

Tie::StdHash  {
    public methods (9) : CLEAR, DELETE, EXISTS, FETCH, FIRSTKEY, NEXTKEY, SCALAR, STORE, TIEHASH
    private methods (0)
    internals: {
        a   "A",
        b   "B",
        c   "C",
        d   "D"
    }
}

Solution 5

The answer depends on what is in your hash. If you have a simple hash a simple

print map { "$_ $h{$_}\n" } keys %h;

or

print "$_ $h{$_}\n" for keys %h;

will do, but if you have a hash that is populated with references you will something that can walk those references and produce a sensible output. This walking of the references is normally called serialization. There are many modules that implement different styles, some of the more popular ones are:

Due to the fact that Data::Dumper is part of the core Perl library, it is probably the most popular; however, some of the other modules have very good things to offer.

Share:
365,099

Related videos on Youtube

Kys
Author by

Kys

Updated on June 05, 2021

Comments

  • Kys
    Kys about 3 years

    I keep printing my hash as # of buckets / # allocated. How do I print the contents of my hash?

    Without using a while loop would be most preferable (for example, a one-liner would be best).

  • friedo
    friedo almost 15 years
    There's no functional difference between your uses of foreach and map. map should be used for list transformations, not in void context to emulate a for-loop
  • FMc
    FMc almost 15 years
    Sleazy: print "@_\n" while @_ = each %h
  • Chas. Owens
    Chas. Owens almost 15 years
    I think you mean print "$_ $h{$_}\n" for (keys %h);, $k doesn't exist in that example.
  • Chas. Owens
    Chas. Owens almost 15 years
    Also, benchmark before making claims about efficiency (or at least qualify the type of efficiency you are talking about). The for loop is faster than the while up to at least 10,000 keys: gist.github.com/151792
  • plusplus
    plusplus almost 15 years
    the original poster might also want to look into the various Data::Dumper options, in particular turning on 'Sortkeys' can be very useful
  • Jonathan Graehl
    Jonathan Graehl almost 15 years
    Of course you're right re: $k. But it's more efficient in Perl 6! :) Yes, you're right on that too. I would never have thought to actually optimize or profile my Perl, but I'm glad to learn this. Of course, each should be more efficient (because there's no extra hash lookup on the key). But it's ~30% slower!
  • justintime
    justintime almost 15 years
    The OP says he has "my hash" that needs printing. This answer is just cleverness for its own sake
  • Kyle Walsh
    Kyle Walsh almost 15 years
    OP was hoping to do it in one line. Was just showing a one-line way of doing it. So that's worthy of a down-vote?
  • MikeKulls
    MikeKulls over 10 years
    Sorry, down vote from me for stuff that hijacks comments for actual functionality. A maintenance programmer could spend all day trying to work out why code like that was printing out unexpected stuff.
  • Axeman
    Axeman over 10 years
    @MikeKulls, np. It's a source filter, so I understand. Also, having written scripts that check every module that I put into production prep that it doesn't use Smart::Comments, I see it from that perspective too. But to the counter, Smart::Comments is pretty well behaved as a scoped module, there shouldn't be output behavior in any module that doesn't also use SC. So, the problem would be isolated to those scopes with a use statement. If you're saying that a maintenance programmer has no responsibility to read the doc on included modules, I can't agree. Still, thanks for commenting
  • MikeKulls
    MikeKulls over 10 years
    I'm not saying they don't have a responsibility but it's not likely to be the first thing they look for. Not ever having seen Smart Comments module before I wouldn't know why the above code was printing something out. I could spend days skipping over the comment and not even process it because comments should do nothing. Making them do something is very bad imo. They can be used for generating documentation etc as long as they don't alter the behaviour of the program.
  • Sos
    Sos about 10 years
    @JonathanDay I was missing that detail and it was helpful! Thanks!
  • Sos
    Sos about 10 years
    having the colors is "neat", but either I am doing something wrong, or using "use Data::Printer; p %var;" doesn't print the arrows in hashes, and for a newbie like me that helps
  • Jacob
    Jacob about 10 years
    @Sosi If you look at the output in the answer, you will see that it doesn't output the => like you expect. It instead always prints the key, several spaces, and then the value. Which helps a human scan over the output.
  • shampoo
    shampoo over 8 years
    What does it mean to add a slash in front of the % ?
  • tetromino
    tetromino over 8 years
    @shampoo slash operator creates a reference, a bit like the & operator in C and C++. The reason it matters in this context is that in Perl, if you call a function with a hash value as the argument, that hash value gets listified and expanded into multiple arguments - so %hsh=("a" => 1, "b" => 2); foo(%hsh); would be equivalent to foo("a", 1, "b", 2). If you instead want the function to operate on the hash itself, you need to pass a reference to the hash: foo(\%hsh); See perldoc.perl.org/perlsub.html#Pass-by-Reference
  • Carlos Sá
    Carlos Sá over 6 years
    Hi, Jonathan Graehl. Sorry, still not understanding. You're saying that each is ~30% slower based on what? Is everytime, for every situation, a gap of 30% ?
  • U. Windl
    U. Windl almost 4 years
    I wonder: Is the while loop slower because of introducing my variables for each iteration? If so, how is the speed when declaring my ($k, $v) before while?