SYNOPSIS

    In function Rinci metadata:

     result => {
         table => {
             spec => {
                 summary => "Employee's' current salary",
                 fields  => {
                     name => {
                         summary => "Employee's name",
                         schema  => 'str*',
                         pos     => 0,
                     },
                     position => {
                         summary => "Employee's current position",
                         schema  => 'str*',
                         pos     => 1,
                     },
                     salary => {
                         summary => "Employee's current monthly salary",
                         schema  => 'float*',
                         pos     => 2,
                     },
                 },
                 pk => 'name',
             },
             # allow_extra_fields => 0,
             # allow_underscore_fields => 0,
         },
         ...
     }

DESCRIPTION

    If your function returns table data, either in the form of array
    (single-column rows):

     ["andi", "budi", "cinta", ...]

    or array of arrays (CSV-like):

     [
       ["andi" , "manager", 12_000_000],
       ["budi" , "staff", 5_000_000],
       ["cinta", "junior manager", 7_500_000],
       # ...
     ]

    or array of hashes (with field names):

     [
       {name=>"andi" , position=>"manager", salary=>12_000_000},
       {name=>"budi" , position=>"staff", salary=> 5_000_000},
       {name=>"cinta", position=>"junior manager", salary=> 7_500_000},
       # ...
     ]

    then you might want to add a table property inside your result property
    of your function metadata. This module offers several things:

      * When your function is run under Perinci::CmdLine, your tables will
      look prettier. This is done via adding table.fields attribute to your
      function result metadata, giving hints to the Data::Format::Pretty
      formatter.

      Also when you use --help (--verbose), the table structure is
      described in the Result section.

      * (NOT YET IMPLEMENTED) When you generate documentation, the table
      specification is also included in the documentation.

      * (NOT YET IMPLEMENTED, IDEA) The user can also perhaps request the
      table specification, e.g. yourfunc --help=result-table-spec, yourfunc
      --result-table-spec.

      * (NOT YET IMPLEMENTED) The wrapper code can optionally validate your
      function result, making sure that your resulting table conforms to
      the table specification.

      * (NOT YET IMPLEMENTED, IDEA) The wrapper code can optionally filter,
      summarize, or sort the table on the fly before returning the final
      result to the user.

      (Alternatively, you can pipe the output to another tool like jq, just
      like a la Unix toolbox philosophy).

SPECIFICATION

    The value of the table property should be a DefHash. Known properties:

      * spec => DEFHASH

      Required. Table data specification, specified using TableDef.

      * allow_extra_fields => BOOL (default: 0)

      Whether to allow the function to return extra fields other than the
      ones specified in spec. This is only relevant when function returns
      array of hashes (i.e. when the field names are present). And this is
      only relevant when validating the table data.

      * allow_underscore_fields => BOOL (default: 0)

      Like allow_extra_fields, but regulates whether to allow any extra
      fields prefixed by an underscore. Underscore-prefixed keys is the
      DefHash's convention of extra keys that can be ignored.

NOTES

    If you return an array or array of arrays (i.e. no field names), you
    might want to add table.fields result metadata so the wrapper code can
    know which element belongs to which field. Example:

     my $table = [];
     push @$table, ["andi", 1];
     push @$table, ["budi", 2];
     return [200, "OK", $table, {"table.fields"=>[qw/name id/]}];

    This is not needed if you return array of hashes, since the field names
    are present as hash keys:

     my $table = [];
     push @$table, {name=>"andi", id=>1};
     push @$table, {name=>"budi", id=>2};
     return [200, "OK", $table];

RESULT METADATA

      * attribute: table.fields => ARRAY OF STR

FAQ

 Why not use the schema property in the result property?

    That is, in your function metadata:

     result => {
         schema => ['array*', of => ['hash*' => keys => {
             name => 'str*',
             position => 'str',
             salary => ['float*', min => 0],
             ...
         }]],
     },

    First of all, table data can come in several forms, either a
    1-dimensional array, an array of arrays, or an array of hashes.
    Moreover, when returning an array of arrays, the order of fields can
    sometimes be changed. The above schema will become more complex if it
    has to handle all those cases.

    With the table property, the intent becomes clearer that we want to
    return table data. We can also specify more aspects aside from just the
    schema.