package Data::Unixish; # just to make PodWeaver happy

our $VERSION = '1.0.0'; # VERSION

1;
# ABSTRACT: Data transformation framework, inspired by Unix toolbox philosophy


__END__
=pod

=head1 NAME

Data::Unixish - Data transformation framework, inspired by Unix toolbox philosophy

=head1 VERSION

version 1.0.0

=head1 SPECIFICATION VERSION

 1.0

=head1 ABSTRACT

This document B<Data::Unixish> (also referred to as B<dux>, for brevity), a Perl
framework for data processing (transformation, conversion, whatever) using the
tried-and-true Unix toolbox philosophy.

=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 PHILOSOPHY

The Unix philosophy says a program should do only one thing and do it well.
Problem is solved by sewing or chaining together a sequence of small,
specialized programs. From Douglas McIlroy, the original developer of Unix
pipelines:

 This is the Unix philosophy: Write programs that do one thing and do it well.
 Write programs to work together. Write programs to handle text streams, because
 that is a universal interface.

In dux, programs translate to functions. dux is essentially a set of guidelines
and tools on how to write such functions.

=head1 GUIDELINES

=over 4

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

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

=item * Arguments should be described in Rinci metadata

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

=item * There are some standard arguments: in, out

B<in> and B<out> are analogous to standard input and output streams, explained
below.

=item * Arguments should have good defaults

=item * Input data is given in C<$args{in}>

It is a "stream", usually actually a reference to array or a tied array.
Function can iterate it as follows:

 while (my ($index, $item) = each @{ $args{in} }) {
     ...
 }

Function MUST NOT slurp it in memory like this (in Perl 5 for() is not lazy):

 # WRONG!
 for (@{ $args{in} }) {
     ...
 }

=item * Output should be written to C<$args{out}>

It is a "stream", usually actually a reference to array or a tied array.
Function can append output as follows:

 while (my ($index, $item) = each @{ $args{in} }) {
     ...
     push @{ $args{out} }, $res;
 }

Function MUST NOT assign to $args{out} directly, e.g.:

 # WRONG!
 $args{out} = [1, 2, 3];

=item * Error messages can be logged to Log::Any

Standard format for error message will be specified in the future.

=item * When processing, undef/invalid/non-applicable value should generally be skipped (passed unchanged)

For example, the B<date> dux function accepts either an integer (assumed as Unix
timestamp) or a L<DateTime> object. Other values like undef, an empty string, or
other kinds of supported objects should not be processed and just passed to the
output stream unprocessed. A warning can be logged if needed.

=back

A well-written dux function can be transformed into a usual Unix command-line
utility (see L<Data::Unixish::CmdLine>).

=head1 NAMESPACE ORGANIZATION

B<Data::Unixish> is the main module and specification.

Each dux function should be written in all-lowercase name, put under
B<Data::Unixish::FUNCTION_NAME> package. The function itself is put in that
package with the same name. For example the L<Data::Unixish::date> package
contains the Data::Unixish::date::date function.

A further subpackaging is allowed, for example:
B<Data::Unixish::English::count_syllables>.

L<Data::Unixish::CmdLine> is a utility to access dux functions from command
line.

=head1 SEE ALSO

L<Rinci> and L<Rinci::function>, another specification to leverage functions.

L<Log::Any>.

=head1 AUTHOR

Steven Haryanto <stevenharyanto@gmail.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Steven Haryanto.

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

=cut

