Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

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
06: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

  • 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?|
    =================