## no critic: TestingAndDebugging::RequireUseStrict
package RowFunc; # just to make PodWeaver happy

# AUTHORITY
# DATE
our $DIST = 'RowFunc'; # DIST
# VERSION

1;
# ABSTRACT: Function that accepts a "row" value

__END__

=pod

=encoding UTF-8

=head1 NAME

RowFunc - Function that accepts a "row" value

=head1 SPECIFICATION VERSION

 1.0

=head1 VERSION

This document describes version 1.0.0 of RowFunc (from Perl distribution RowFunc), released on 2024-12-10.

=head1 ABSTRACT

This document specifies "row functions", a specific kind of Perl functions that
accept a single "row" value.

=head1 STATUS

Early draft. The 1.0 series does not guarantee full backward compatibility
between revisions, so caveat implementor. However, major incompatibility will
bump the version to 1.1.

=head1 SPECIFICATION

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in RFC 2119.

=over

=item * Function must accept a hash argument C<%args>

This future-proofs the function when more and more arguments are added.

=item * Function must return an enveloped result.

For xample:

 [200, "OK", ["andy", "director", 42]]

=item * Arguments should be described in Rinci metadata

See L<Rinci> and L<Rinci::function> for more details.

=item * There is a required argument: row

It can be specified with schema C<< [array => of=>"str*"] >>, for example, but
actually any kind of schema is allowed. It should also be specified with these
properties:

 req => 1

Default value is optional.

=item * Other arguments are allowed and should have good defaults

=item * When function fails (i.e. it cannot transform the input value) it should return an error result

Examples:

 [404, "File not found"]
 [400, "Cannot take square root of a negative number"]
 [409, "File already exists"]

=item * The function should ideally not have side effects. It should just produce a transformed value

=item * The function should be named C<func> under the C<RowFunc::*> namespace

=back

A well-written RowFunc function should be readily usable as a CLI or as a
transformer in a CLI utility.

An example row function:

 use strict;
 use warnings;

 package RowFunc::Str::add_default;

 our %SPEC;
 $SPEC{'func'} = {
     v => 1.1,
     summary => 'Fill empty/undefined fields with specified default value',
     args => {
         row => {schema => [array => [of=>'str*']], req=>1},
         default => {schema => 'str*', req=>1},
     },
 };
 sub func {
     my %args = @_;
     for (@{ $args{row} }) { $_ = $args{default} if !defined || !length }
     [200, "OK", $args{row}];
 }
 1;

=head1 NAMESPACE ORGANIZATION

B<RowFunc> is the specification.

Actual row functions are put in C<RowFunc::*>, preferrably under suitable
subnamespaces named using "CamelCase" style except the last element ("the name
of the RowFunc") which should be written using "snake_case" style.

Row functions that return a single scalar value should be named with "_value"
suffix, for example: L<RowFunc::Math::sum_value>, L<RowFunc::Math::avg_value>.

=head1 FAQ

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/RowFunc>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-RowFunc>.

=head1 SEE ALSO

=head2 Related specifications

L<Rinci> and L<Rinci::function>, the base specification upon which we built.

L<CellFunc>, like RowFunc but for functions that accept a single value.

L<Unixish>, which is a specification for function that consumes and produces
"streams" instead of a "row" value.

=head2 Utility modules

L<App::rowfunc> lets you call specified row function and feed it data.

L<App::dux> for Unixish.

Bridges between us and C<Unixish>: L<RowFunc::Unixish::from_dux> and
L<Data::Unixish::from_rowfunc>.

Some applications let you specify row functions by name to transform data, e.g.
L<App::CSVUtils>'s L<csv-rowfunc>.

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 CONTRIBUTING


To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.

Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:

 % prove -l

If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2024 by perlancar <perlancar@cpan.org>.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=RowFunc>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=cut
