Command-Run
view release on metacpan or search on metacpan
nofork mode. Layer changes are now undone before restoring
the handles, so long-running processes no longer degrade.
With the fix, nofork with :encoding is 50x faster than
before (316/s -> 15,997/s) and raw mode is optional rather
than necessary.
- Raw mode no longer leaks the :utf8 flag to the caller's
standard filehandles.
1.01 2026-06-03T08:12:11Z
- Tmpfile: add raw mode (new(raw => 1)) for byte-transparent
temporary files, opening the handle with :raw instead of
:encoding(utf8) so byte streams (qx// output, pre-encoded UTF-8)
are stored and read back unchanged without double encoding
1.00 2026-04-27T01:50:48Z
- Tmpfile: probe fd-path with the actual allocated fd to detect
FreeBSD without fdescfs (where /dev/fd/0,1,2 exist but /dev/fd/N
for N>2 do not); prefer /proc/self/fd over /dev/fd; path() now
returns undef when no usable fd-path is available
A key advantage of this mechanism is that **callee modules typically
require no modification** to work with nofork+raw mode.
Many Perl modules use `use open` pragma or equivalent to set up
encoding layers on standard I/O:
package App::ansicolumn;
use open IO => ':utf8', ':std'; # sets :encoding(utf8) on STDIO
This works transparently because of execution order. When using
nofork mode with method chaining:
require App::ansicolumn; # (1) module loaded here
Command::Run->new
->command(\&ansicolumn, @args)
->with(stdin => $text, nofork => 1, raw => 1)
->update # (2) STDOUT redirected here
->data;
At step (1), `require` loads the module and `use open ':std'`
lib/Command/Run.pm view on Meta::CPAN
A key advantage of this mechanism is that B<callee modules typically
require no modification> to work with nofork+raw mode.
Many Perl modules use C<use open> pragma or equivalent to set up
encoding layers on standard I/O:
package App::ansicolumn;
use open IO => ':utf8', ':std'; # sets :encoding(utf8) on STDIO
This works transparently because of execution order. When using
nofork mode with method chaining:
require App::ansicolumn; # (1) module loaded here
Command::Run->new
->command(\&ansicolumn, @args)
->with(stdin => $text, nofork => 1, raw => 1)
->update # (2) STDOUT redirected here
->data;
At step (1), C<require> loads the module and C<use open ':std'>
lib/Command/Run/Tmpfile.pm view on Meta::CPAN
=item B<new>([raw => I<bool>])
Create a new temporary file object.
By default the underlying file handle is opened with the
C<:encoding(utf8)> layer, so character strings are encoded to UTF-8 on
write and decoded on read.
When C<raw> is true, the C<:raw> layer is used instead, making the file
a transparent byte container: whatever bytes are written are stored and
read back unchanged. Use this when you write data that is already a
byte stream (for example the output of an external command captured with
C<qx//>, or the result of C<encode 'utf8', ...>), to avoid double
encoding.
my $tmp = Command::Run::Tmpfile->new(raw => 1);
$tmp->write($bytes)->rewind;
system("cat", $tmp->path); # bytes pass through unchanged
Note that C<raw> means C<:raw> (no conversion at all), which is distinct
t/01_tmpfile.t view on Meta::CPAN
$enc->write($bytes)->flush->rewind;
my $efh = $enc->fh; binmode $efh;
my $eout = do { local $/; <$efh> };
isnt $eout, $bytes, 'default mode re-encodes byte string';
# raw mode stores bytes unchanged
my $raw = Command::Run::Tmpfile->new(raw => 1);
$raw->write($bytes)->flush->rewind;
my $rfh = $raw->fh; binmode $rfh;
my $rout = do { local $/; <$rfh> };
is $rout, $bytes, 'raw mode is byte-transparent';
is length($rout), 6, 'raw mode stores 6 bytes';
}
done_testing;
( run in 4.341 seconds using v1.01-cache-2.11-cpan-7fcb06a456a )