Stories
Slash Boxes
Comments

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Tuesday June 24, 2008
07:47 AM

Easy Text Tables!

[ #36762 ]
I really like the Text::Table module, but its use can be a bit cryptic at times. A basic table can look like this:

Time    Test
18m 12s t/acceptance.t
4m 17s  t/aggregate.t
2m 12s  t/unit/api/spider_and_validate.t
0m 53s  t/standards/use.t
0m 21s  t/system/both/import/log/search.t
0m 20s  t/system/both/import/log/pager.t
0m 18s  t/test_class_tests.t
0m 16s  t/unit/db/migrations.t
0m 14s  t/unit/piptest/pprove/testdb.t
0m 12s  t/system/both/import/log/log.t

That's nice and all, but I'd rather have this:

+---------+-----------------------------------+
| Time    | Test                              |
+---------+-----------------------------------+
| 18m 12s | t/acceptance.t                    |
| 4m 17s  | t/aggregate.t                     |
| 2m 12s  | t/unit/api/spider_and_validate.t  |
| 0m 53s  | t/standards/use.t                 |
| 0m 21s  | t/system/both/import/log/search.t |
| 0m 20s  | t/system/both/import/log/pager.t  |
| 0m 18s  | t/test_class_tests.t              |
| 0m 16s  | t/unit/db/migrations.t            |
| 0m 14s  | t/unit/piptest/pprove/testdb.t    |
| 0m 12s  | t/system/both/import/log/log.t    |
+---------+-----------------------------------+

Have fun reading the docs to figure that out :) Here's my generic function for printing tables like that. You get no control over formatting.

use Text::Table;

my @rows = code_to_get_rows();

print make_table(
    [qw/Time Test/],
    \@rows,
);

sub make_table {
    my ( $headers, $rows ) = @_;

    my @rule      = qw(- +);
    my @headers   = \'| ';
    push @headers => map { $_ => \' | ' } @$headers;
    pop  @headers;
    push @headers => \' |';

    unless ('ARRAY' eq ref $rows
        && 'ARRAY' eq ref $rows->[0]
        && @$headers == @{ $rows->[0] }) {
        croak(
            "make_table() rows must be an AoA with rows being same size as headers"
        );
    }
    my $table = Text::Table->new(@headers);
    $table->rule(@rule);
    $table->body_rule(@rule);
    $table->load(@$rows);

    return $table->rule(@rule),
           $table->title,
           $table->rule(@rule),
           map({ $table->body($_) } 0 .. @$rows),
           $table->rule(@rule);
}

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
    • Never saw that module before. I don't understand why it requires that I pass in the width when the calculation is trivial. Sometimes module interfaces mystify me.

  • I wrote Text::TabularDisplay [cpan.org] to do exactly that.
    --
    (darren)
    • Well, Text::SimpleTable is clearly more Table 2.0, what with the rounded corners and everything.

      • Well, Text::SimpleTable is clearly more Table 2.0, what with the rounded corners and everything.
        And it's from 2005, too -- well ahead of its time. It looks pretty similar to Text::TabularDisplay, otherwise. I was specifically going for the mysql client look, as part of a similar command line client for $WORK, when I wrote it, so I don't think the rounded corners occurred to me at the time.
        --
        (darren)
  • Have fun reading the docs to figure that out :)

    I'm skeptical. I admit to having ever used Text::Table before, but not much, and it didn't take more than a glance at the docs to figure out how to do what you want:

    my $t = Text::Table->new(\'| ', 'Time', \' | ', 'Text', \' |');
    $t->load(... some data ...);
    my $rule = $t->rule(qw(- +));
    print $rule, $t->head, $rule, $t->body, $rule;

    I'm not claiming to be overly fond of the interface -- any time I have to do \'foo' it trips my fingers up -- but I've read documentation that's far worse

    --
    hdp.
  • All these table formatters. I never knew. I just use the 'format' built-in.

    man perlform

    Perhaps I should investigate them, because I don't know how to write argument lines to 'format' that match the number of values in an array. The number of values is variable. The argument lines are fixed.

    Perhaps I should declare different formats for each of the possible number of values, because I have only a small number of different possible numbers of values.

  • My module Text::FormatTable (rather old and not really actively developed) can do word-wrapping and outputs tables like this:

         a| b     c
    =================
    this a| oh,   yep
    test,| cool,
    a nice| a
      test| test!
    ------+----------
       you| yes,  z
      mean| it
      it's| is.
    really|
         a|
    test?|
    =================