Karel Bílek
Karel Bílek

Reputation: 37694

What are the arguments to IO::Pipe constructors in Perl?

What are the arguments used in IO::Pipe perl constructors?

What I see in documentation is:

IO::Pipe::new optionally takes two arguments, which should be objects blessed into IO::Handle, or a subclass thereof. These two objects will be used for the system call to pipe. If no arguments are given then method handles is called on the new IO::Pipe object.

I don't really get what it means. Can someone provide an example/explanation?

Upvotes: 3

Views: 593

Answers (2)

daxim
daxim

Reputation: 39158

It's straight-forward once you learn object-oriented programming. See the Stack Overflow archive for recommendations of appropriate teaching material. To follow the explanation below, you need to keep in mind that bless works not only on hashrefs.

You should also already completely understand what the underlying pipe POSIX system call does, and what a file descriptor is in C and Perl and what all sort of things it can point to, and how a FD is passed around in Perl as a glob. If these pieces are confusing, too, open separate questions and reference this one.

use IO::Pipe qw();
my $pipe = IO::Pipe->new($reader, $writer);

tl;dr version: $reader and $writer are expected to be file handles you or something else has opened earlier, most likely from the open function or a IO::File instance. The documentation mentions IO::Handle foremost because likely you want to also pipe FDs that are not proper files, but standard streams (STDIN, STDOUT) connected to certain processes, and for this purpose IO::Handle suffices.


Detailed version:

The $reader and $writer variables are expected to contain object instances of type IO::Handle ($reader is-a IO::Handle). IO::Handle is rarely used, more often its subclass IO::File.

use IO::File qw();
my $reader = IO::File->new('/usr/src/linux/COPYING', 'r');
# bless(*Symbol::GEN0 => 'IO::File')
$reader->fileno
# 6
$reader->can('getline')
# true

use IO::File::WithPath qw();
my $writer = IO::File::WithPath->new('/tmp/foobar', 'w');
$writer->fileno
# 7
$writer->can('print')
# true

For historical reasons, a lot of things that are not strict subclasses of IO::Handle work, too. It suffices that they merely behave like IO::Handle ("duck type"), i.e. provide some of the methods mentioned in the documentation, and those need not be inherited from IO::Handle.

open my $other_reader, '<', '/usr/src/linux/COPYING';
# \*{'::$other_reader'}
$other_reader->fileno;
# 8
$other_reader->can('getline');
# false, but works anyway, see http://p3rl.org/IO::Handle#BUGS

use File::Temp qw(tempfile);
my ($other_writer) = tempfile;
# \*{'File::Temp::$fh'}
$other_writer->fileno;
# 9
$other_writer->can('print')
# false, but works anyway, see http://p3rl.org/IO::Handle#BUGS

use IO::String qw();
my $s = IO::String->new("foo\nbar\nbaz");
# bless(*Symbol::GEN1 => 'IO::String')
$s->fileno
# undef
$s->can('getline')
# true

### TODO
use File::Map qw(map_handle);
map_handle my $map, '/boot/vmlinuz';  # ???

### TODO   some popen examples

Upvotes: 1

choroba
choroba

Reputation: 241968

See man 3p pipe:

The pipe() function shall create a pipe and place two file descriptors, one each into the arguments fildes[0] and fildes[1], that refer to the open file descriptions for the read and write ends of the pipe.

Try it to see.

Upvotes: 0

Related Questions