views:

775

answers:

9

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 (ex: a one-line would be best)

+3  A: 

easy:

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

elegant but actually 30% slower (!):

while (my ($k,$v)=each %h){print "$k $v\n"}
wrang-wrang
Sleazy: print "@_\n" while @_ = each %h
FM
I think you mean `print "$_ $h{$_}\n" for (keys %h);`, `$k` doesn't exist in that example.
Chas. Owens
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: http://gist.github.com/151792
Chas. Owens
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!
wrang-wrang
+12  A: 

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
        };
tetromino
could you add the result of that bit of code?
Ape-inago
OK, added the output.
tetromino
the original poster might also want to look into the various Data::Dumper options, in particular turning on 'Sortkeys' can be very useful
plusplus
+1  A: 

If you want to be pedantic and keep it to one line (without use statements and shebang), then I'll sort of piggy back off of tetromino's answer and suggest:

print Dumper( { 'abc' => 123, 'def' => [4,5,6] } );

Not doing anything special other than using the anonymous hash to skip the temp variable ;)

Kyle Walsh
The OP says he has "my hash" that needs printing. This answer is just cleverness for its own sake
justintime
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?
Kyle Walsh
A: 

Looping:

foreach(keys %my_hash) { print "$_ / $my_hash{$_}\n"; }

Functional

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

But for sheer elegance, I'd have to choose wrang-wrang's. For my own code, I'd choose my foreach. Or tetro's Dumper use.

Paul Nathan
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
friedo
it would be interesting to see the 'byte code' results of each... I wonder if map is more or less efficient.
Ape-inago
A: 

One option is

print %hash, "\n";

but that is not pretty. You could use Data::Dumper, but if you have a particular output format in mind, it may not be straightforward to tailor Data::Dumper to generate that.

Perl's each function allows you to iterate through the keys of a hash when used in scalar context (this way, Perl does not have to allocate a large temporary array to hold the keys returned by keys):

printf "%12s => %-12s\n", $_, $hash{$_} while $_ = each %hash;

On the other hand, using keys allows you to walk through the keys in a predefined order (see also the Schwartzian Transform regarding efficiency in that context).

Sinan Ünür
+2  A: 

My favorite: Smart::Comments

use Smart::Comments;
# ...

### %hash

That's it.

Axeman
That's cool. +1
Kyle Walsh
+1  A: 

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.

Chas. Owens
A: 

The easiest way in my experiences is to just use Dumpvalue.

use Dumpvalue;
...
my %hash = { key => "value", foo => "bar" };
my $dumper = new DumpValue();
$dumper->dumpValue(\%hash);

Works like a charm and you don't have to worry about formatting the hash, as it outputs it like the Perl debugger does (great for debugging). Plus, Dumpvalue is included with the stock set of Perl modules, so you don't have to mess with CPAN if you're behind some kind of draconian proxy (like I am at work).

Weegee
+1  A: 

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.

use Data::Dump = 'dump';

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