Rinci::FAQ(3pm)

πŸ“¦
version 1.1.104 Β· 3 versions
, in debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ NAME ✨

Rinci::FAQ β€” bestie, it's literally the FAQ on Rinci πŸ’–

(Also, hi, this is a section 3pm page from the User Contributed Perl Documentation, so you know it's legit.)


🌸 VERSION 🌸

This document describes version 1.1.104 of Rinci::FAQ (from Perl distribution Rinci), released on 2023-09-30. πŸŽ€


πŸ’… FAQ πŸ’…

πŸ¦‹ Rinci::function πŸ¦‹

  • Why do you make enveloped result an array instead of hash? 😭

Okay so like, a hash-based enveloped result could look something like this:

{status=>200, message=>"OK", result=>42, meta1=>..., meta2=>...}

The vibe of that is a single container, which is nice, but I picked array because it's so much briefer for the simple cases β€” and bestie, the simple cases are literally the majority. Like:

[200]        # versus {status=>200}
[200, "OK"]  # versus {status=>200, message=>"OK"}

And when you're actually handling an enveloped result, the array version is shorter too:

if ($res->[0] == 200) { ... }
# versus: if ($res->{status} == 200) { ... }

print "Error $res->[0] - $res->[1]";
# versus: print "Error $res->{status} - $res->{message}";

Not gonna lie, the hash version is more obvious if it's your first time reading it. But after literally just some amount of time, $res->[0] and $res->[1] become obvious too, as long as you use it consistently. 🫢

And as a bonus?? Arrays are faster and more space-efficient than hashes. Slay.

  • How do you indicate transient/temporary vs permanent errors? πŸ€”

Some protocols β€” SMTP, POP, those girlies β€” define 4xx codes as temporary errors and 5xx as permanent ones. That gives clients a lil clue about whether to retry or not. HTTP, which Rinci is modelled after, does not provide that distinction in its status codes. BUT. Rinci defines a perm_err result metadata that you can use for exactly this purpose, e.g.:

[500, "Can't submit mail, we are being blocked by RBL", undef,
 {perm_err=>0}]

[500, "Can't submit mail, destination address does not exist", undef,
 {perm_err=>1}]
  • How to handle binary data? 🧚

To accept binary data, set one or more arguments as having the schema type buf (instead of str):

args => {
    data => { schema => 'buf*', req=>1 },
}

To return binary data, set result's schema type to buf, e.g.:

result => { schema => 'buf*' }

And for handling binary data when you're writing Perl-based command-line applications, go peek at Perinci::CmdLine::Manual::Examples. πŸ“š

  • How to accept partial data? πŸ“

First, set an argument property partial to true to signify that this argument accepts a partial value. Then you can call with the special arguments -arg_len, -arg_part_start, -arg_part_len. See Rinci::function for more deets. Riap::HTTP can also do this via HTTP Content-Range. ✨

  • How to accept streaming input? 🌊

Many program environments (like in Unix) have the concept of standard input. Rinci provides a thin abstraction over this. You can set the argument property stream to true. This way, in most implementations β€” like in Perl β€” your function will receive the argument value as a filehandle which it can then read from. See the partial property in the args function metadata property in Rinci::function for an example.

Your function can also read from standard input directly, but bestie, that means you can't use conveniences like the cmdline_src, where the command-line framework can supply an argument value for you from various sources including standard input and/or files. 😭

  • How to produce streaming output? πŸ’«

Many program environments (like in Unix) have the concept of standard output. To produce an output stream, you can set the result metadata property stream to true. And then in the result you can put a filehandle or an object that responds to getline/getitem methods. Periodt.

  • What is the difference between accepting partial data and streaming input? πŸ‘€

If a function accepts partial data, to send a large amount of data without taking up too much memory, a caller needs to break the data into several parts and call the function several times, each with a different part.

If a function accepts a stream input, to send a large amount of data a caller can send a filehandle/iterator object from which the function can read the data iteratively.

Stream input is easier and simpler for the function writer to write. A caller also only needs to call the function once instead of multiple times. However β€” and this is the catch β€” there is no resume capability. πŸ’€

On the other hand, partial input data is easier to implement with Riap::HTTP, as it maps rather closely to HTTP Content-Range.

If you are uploading a large amount of data over a network to a function, partial input data is preferred because of its ease to work with HTTP and its resume ability. πŸ”₯

However, if input is really a stream (i.e. unknown/infinite length), then streaming input is the option to use.

  • What is the difference between returning partial result and streaming output? πŸŒ€

If a function can return partial result, to retrieve a large result from a function a caller can call several times and each time request to retrieve parts of the result.

If a function returns output stream, a caller can then retrieve data from the stream iteratively.

Output stream is easier to handle by the caller. The caller also only needs to call once instead of multiple times. However, there is no resume capability. πŸ’€

On the other hand, partial result is easier to implement with Riap::HTTP, as it maps rather closely to HTTP


🌈 HOMEPAGE 🌈

Please visit the project's homepage at <https://metacpan.org/release/Rinci>. πŸ πŸ’–


πŸŽ€ SOURCE πŸŽ€

Source repository is at <https://github.com/perlancar/perl-Rinci>. πŸ‘‘


⭐ AUTHOR ⭐

perlancar <perlancar@cpan.org> β€” the main character, fr fr 🫢


πŸ’œ CONTRIBUTING πŸ’œ

To contribute, you can send patches by email/via RT, or send pull requests on GitHub. We love that for you. πŸ₯°

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 Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, 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. πŸ™ˆ


This software is copyright (c) 2023, 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012 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. πŸŽ‰


πŸ”₯ BUGS πŸ”₯

Please report any bugs or feature requests on the bugtracker website <https://rt.cpan.org/Public/Dist/Display.html?Name=Rinci>. πŸ›

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. Iykyk. ✨


okay that's the whole vibe check, bestie πŸ’… This was perl v5.38.2, documented on 2024-01-20, and you just read Rinci::FAQ(3pm). go forth and slay πŸ’–πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from