pericmd 021: Formatting output

So, here’s another way you can be lazy if you use Perinci::CmdLine: your function usually needs to return a data structure instead of formatted text. Perinci::CmdLine is the one that will format your output. This is useful because if the function is used as a normal Perl function or for HTTP API function, data structures are readily usable instead of formatted text which must be (re-)parsed. In these days of JSON API’s, this works out very nicely.

So how does Perinci::CmdLine format the data structure? Realizing that 2D table (including a list of lines, which is a one-column table) is the format that is very common, here are the rules that Perinci::CmdLine::Lite uses:

  1. If result is undef, print nothing.
  2. If result is a string, print the string. Add ending newline unless the string already has it.
  3. If result is an array of strings (aos), print each string in its own lines.
  4. If result is an array of arrays of strings (aoaos), print as table (using Text::Tiny::Table).
  5. If result is an array of hashes of strings (aohos), print as table. The column names will be taken from the keys of the hashes.
  6. If result is a hash of strings, print as two-column table. First column is keys, second column is values.
  7. Otherwise, print as JSON.

This set of rules is used under the default output format (text) and under interactive mode, which means that the script output is not piped to another command (this is detected automatically, using -t STDOUT). Under non-interactive mode, the table output will be simplified as just tab-separated values.

Other formats available are text-simple (just like text, but forces non-interactive mode rendering, which means tables are always printed as simple tab-separated values) and text-pretty (just like text, but forces interactive mode rendering, which means tables are always rendered using Text::Tiny::Table so it’s prettier). There is also json format which forces JSON rendering no matter what kind of data it receives and its variant json-pretty (just like json but pretty-print the output).

FYI, the ::Classic backend supports more sophisticated rules and table rendering using Text::ANSITable, supporting colors, multiline cells, Unicode borders, and full-width Unicode characters. It also uses Data::Format::Pretty which can output YAML and other formats which are more capable than JSON. But all these result in more dependencies and being slower to render table/output, so their use is avoided by the ::Lite backend. For now, we’ll only take a look at the default ::Lite backend.

Let’s use a real Perinci::CmdLine-based application as examples: App::lcpan. I’m going to show you the JSON output first to let you see the data structure, and then the default text output to see the formatted text.

Below is how an array of strings would be displayed:

% lcpan modules Perinci::CmdLine:: --format json-pretty
[
   200,
   "OK (envelope added by Perinci::Access::Lite)",
   [
      "Perinci::CmdLine::Any",
      "Perinci::CmdLine::Base",
      "Perinci::CmdLine::Base::Patch::DumpAndExit",
      "Perinci::CmdLine::ColorTheme::Default",
      "Perinci::CmdLine::Dump",
      "Perinci::CmdLine::Examples",
      "Perinci::CmdLine::Help",
      "Perinci::CmdLine::Lite",
      "Perinci::CmdLine::NonOO",
      "Perinci::CmdLine::Role::Help",
      "Perinci::CmdLine::Server",
      "Perinci::CmdLine::Util",
      "Perinci::CmdLine::Util::Config",
      "Perinci::CmdLine::dux",
      "Perinci::CmdLine::fatten",
      "Perinci::Examples::Bin::Any",
      "Perinci::Examples::Bin::Any::Multi",
      "Perinci::Examples::Bin::Lite"
   ],
   {}
]

% lcpan modules Perinci::CmdLine::
Perinci::CmdLine::Any
Perinci::CmdLine::Base
Perinci::CmdLine::Base::Patch::DumpAndExit
Perinci::CmdLine::ColorTheme::Default
Perinci::CmdLine::Dump
Perinci::CmdLine::Examples
Perinci::CmdLine::Help
Perinci::CmdLine::Lite
Perinci::CmdLine::NonOO
Perinci::CmdLine::Role::Help
Perinci::CmdLine::Server
Perinci::CmdLine::Util
Perinci::CmdLine::Util::Config
Perinci::CmdLine::dux
Perinci::CmdLine::fatten
Perinci::Examples::Bin::Any
Perinci::Examples::Bin::Any::Multi
Perinci::Examples::Bin::Lite

Below is array of hashes of strings (aohos):

% lcpan modules Perinci::CmdLine:: --detail --format json-pretty
[
   200,
   "OK (envelope added by Perinci::Access::Lite)",
   [
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Any",
         "name" : "Perinci::CmdLine::Any",
         "version" : "0.08"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Lite",
         "name" : "Perinci::CmdLine::Base",
         "version" : "0.83"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Dump",
         "name" : "Perinci::CmdLine::Base::Patch::DumpAndExit",
         "version" : "0.02"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine",
         "name" : "Perinci::CmdLine::ColorTheme::Default",
         "version" : "1.44"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Dump",
         "name" : "Perinci::CmdLine::Dump",
         "version" : "0.02"
      },
      {
         "author" : "SHARYANTO",
         "dist" : "Perinci-CmdLine-Examples",
         "name" : "Perinci::CmdLine::Examples",
         "version" : null
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Help",
         "name" : "Perinci::CmdLine::Help",
         "version" : "0.02"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Lite",
         "name" : "Perinci::CmdLine::Lite",
         "version" : "0.83"
      },
      {
         "author" : "SHARYANTO",
         "dist" : "Perinci-CmdLine-NonOO",
         "name" : "Perinci::CmdLine::NonOO",
         "version" : "0.01"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine",
         "name" : "Perinci::CmdLine::Role::Help",
         "version" : "1.44"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Server",
         "name" : "Perinci::CmdLine::Server",
         "version" : "0.04"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Util",
         "name" : "Perinci::CmdLine::Util",
         "version" : "0.06"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-CmdLine-Lite",
         "name" : "Perinci::CmdLine::Util::Config",
         "version" : "0.83"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "App-dux",
         "name" : "Perinci::CmdLine::dux",
         "version" : "1.48"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "App-fatten",
         "name" : "Perinci::CmdLine::fatten",
         "version" : "0.28"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-Examples-Bin-Any",
         "name" : "Perinci::Examples::Bin::Any",
         "version" : "0.05"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-Examples-Bin-Any",
         "name" : "Perinci::Examples::Bin::Any::Multi",
         "version" : "0.05"
      },
      {
         "author" : "PERLANCAR",
         "dist" : "Perinci-Examples-Bin-Lite",
         "name" : "Perinci::Examples::Bin::Lite",
         "version" : "0.04"
      }
   ],
   {}
]

% lcpan modules Perinci::CmdLine:: --detail
+-----------+---------------------------+--------------------------------------------+---------+
| author    | dist                      | name                                       | version |
| PERLANCAR | Perinci-CmdLine-Any       | Perinci::CmdLine::Any                      | 0.08    |
| PERLANCAR | Perinci-CmdLine-Lite      | Perinci::CmdLine::Base                     | 0.83    |
| PERLANCAR | Perinci-CmdLine-Dump      | Perinci::CmdLine::Base::Patch::DumpAndExit | 0.02    |
| PERLANCAR | Perinci-CmdLine           | Perinci::CmdLine::ColorTheme::Default      | 1.44    |
| PERLANCAR | Perinci-CmdLine-Dump      | Perinci::CmdLine::Dump                     | 0.02    |
| SHARYANTO | Perinci-CmdLine-Examples  | Perinci::CmdLine::Examples                 |         |
| PERLANCAR | Perinci-CmdLine-Help      | Perinci::CmdLine::Help                     | 0.02    |
| PERLANCAR | Perinci-CmdLine-Lite      | Perinci::CmdLine::Lite                     | 0.83    |
| SHARYANTO | Perinci-CmdLine-NonOO     | Perinci::CmdLine::NonOO                    | 0.01    |
| PERLANCAR | Perinci-CmdLine           | Perinci::CmdLine::Role::Help               | 1.44    |
| PERLANCAR | Perinci-CmdLine-Server    | Perinci::CmdLine::Server                   | 0.04    |
| PERLANCAR | Perinci-CmdLine-Util      | Perinci::CmdLine::Util                     | 0.06    |
| PERLANCAR | Perinci-CmdLine-Lite      | Perinci::CmdLine::Util::Config             | 0.83    |
| PERLANCAR | App-dux                   | Perinci::CmdLine::dux                      | 1.48    |
| PERLANCAR | App-fatten                | Perinci::CmdLine::fatten                   | 0.28    |
| PERLANCAR | Perinci-Examples-Bin-Any  | Perinci::Examples::Bin::Any                | 0.05    |
| PERLANCAR | Perinci-Examples-Bin-Any  | Perinci::Examples::Bin::Any::Multi         | 0.05    |
| PERLANCAR | Perinci-Examples-Bin-Lite | Perinci::Examples::Bin::Lite               | 0.04    |
+-----------+---------------------------+--------------------------------------------+---------+

% lcpan modules Perinci::CmdLine:: --detail --format text-simple
PERLANCAR       Perinci-CmdLine-Any     Perinci::CmdLine::Any   0.08
PERLANCAR       Perinci-CmdLine-Lite    Perinci::CmdLine::Base  0.83
PERLANCAR       Perinci-CmdLine-Dump    Perinci::CmdLine::Base::Patch::DumpAndExit      0.02
PERLANCAR       Perinci-CmdLine Perinci::CmdLine::ColorTheme::Default   1.44
PERLANCAR       Perinci-CmdLine-Dump    Perinci::CmdLine::Dump  0.02
SHARYANTO       Perinci-CmdLine-Examples        Perinci::CmdLine::Examples
PERLANCAR       Perinci-CmdLine-Help    Perinci::CmdLine::Help  0.02
PERLANCAR       Perinci-CmdLine-Lite    Perinci::CmdLine::Lite  0.83
SHARYANTO       Perinci-CmdLine-NonOO   Perinci::CmdLine::NonOO 0.01
PERLANCAR       Perinci-CmdLine Perinci::CmdLine::Role::Help    1.44
PERLANCAR       Perinci-CmdLine-Server  Perinci::CmdLine::Server        0.04
PERLANCAR       Perinci-CmdLine-Util    Perinci::CmdLine::Util  0.06
PERLANCAR       Perinci-CmdLine-Lite    Perinci::CmdLine::Util::Config  0.83
PERLANCAR       App-dux Perinci::CmdLine::dux   1.48
PERLANCAR       App-fatten      Perinci::CmdLine::fatten        0.28
PERLANCAR       Perinci-Examples-Bin-Any        Perinci::Examples::Bin::Any     0.05
PERLANCAR       Perinci-Examples-Bin-Any        Perinci::Examples::Bin::Any::Multi      0.05
PERLANCAR       Perinci-Examples-Bin-Lite       Perinci::Examples::Bin::Lite    0.04
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s