How can I print the contents of a hash in Perl?
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.
Related videos on Youtube
Kys
Updated on June 05, 2021Comments
-
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 almost 15 yearsThere's no functional difference between your uses of
foreach
andmap
.map
should be used for list transformations, not in void context to emulate a for-loop -
FMc almost 15 yearsSleazy: print "@_\n" while @_ = each %h
-
Chas. Owens almost 15 yearsI think you mean
print "$_ $h{$_}\n" for (keys %h);
,$k
doesn't exist in that example. -
Chas. Owens almost 15 yearsAlso, benchmark before making claims about efficiency (or at least qualify the type of efficiency you are talking about). The
for
loop is faster than thewhile
up to at least 10,000 keys: gist.github.com/151792 -
plusplus almost 15 yearsthe original poster might also want to look into the various Data::Dumper options, in particular turning on 'Sortkeys' can be very useful
-
Jonathan Graehl almost 15 yearsOf 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 almost 15 yearsThe OP says he has "my hash" that needs printing. This answer is just cleverness for its own sake
-
Kyle Walsh almost 15 yearsOP 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 over 10 yearsSorry, 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 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 over 10 yearsI'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 about 10 years@JonathanDay I was missing that detail and it was helpful! Thanks!
-
Sos about 10 yearshaving 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 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 over 8 yearsWhat does it mean to add a slash in front of the % ?
-
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 tofoo("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á over 6 yearsHi, 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 almost 4 yearsI wonder: Is the
while
loop slower because of introducingmy
variables for each iteration? If so, how is the speed when declaringmy ($k, $v)
beforewhile
?