Search code examples
perlhashconventions

accessing "pair hash" references used for column specification


I'm building a small library that transforms log data into a CSV-like file that can be imported by spreadsheet software. For the output, I'm interested in an option to display human-friendly captions for the table columns if needed. This should be an option so that the tool can also be used with minimal effort. I came up with an array for column specification that contains plain scalars for keys or hash references with a pair of key and value. I'm accessing these via keys and values which looks a bit strange to me.

Is there a simpler way to access key and value of a hash that contains just a pair?

(I tried to simplify the code as much as possible.)

#!/usr/bin/perl -w
use strict;
use warnings;

# some sample data
my @rows = (
    {x => 1, y => 2},
    {y => 5, z => 6},
    {x => 7, z => 9},
);

sub print_table {
    my @columns = @_; # columns of interest with optional header replacement
    my @keys; # for accessing the data values 
    my @captions; # for display on column headers
    for (@columns) {
        if (ref($_) eq 'HASH') {
            push @keys, keys %$_;
            push @captions, values %$_;
        } else {
            push @keys, $_;
            push @captions, $_;
        }
    }
    print join ("\t", @captions), "\n";
    for my $row (@rows) {
        print join ("\t", (map {$row->{$_} // ''} @keys)), "\n";
    }
}

print_table({x=>'u'}, 'y');

Solution

  • All you need:

    my ($k, $v) = %hash;
    

    So

    my ($k, $v) = %$_;
    push @keys,     $k;
    push @captions, $v;
    

    or

    push @keys,     ( %$_ )[0];
    push @captions, ( %$_ )[1];