Home > Back-end >  What is a "handle" in Perl?
What is a "handle" in Perl?

Time:09-02

Wondering what the handle is in Perl.

I can see file handle, directory handle..etc but want to know the meaning of the handle in Perl.

For example, in IO::Pipe, I can see below explain. And want to make clear the meaning of "becomes a handle"?

reader ([ARGS])

The object is re-blessed into a sub-class of IO::Handle, 
and becomes a handle at the reading end of the pipe. If 
ARGS are given then fork is called and ARGS are passed 
to exec.

Also could you please explain the meaning of bless?

CodePudding user response:

A handle is an way to get to something without actually being that thing. A handle has an interface to interact with something managed by system (or something else).

Start with the idea of a scalar. Defining a simple scalar stores a value and that value is actually in the memory of your program. In very simplistic terms, you manage that resource directly and wholly within your program. You don't need to ask the system to do increment the variable for you:

 my $n = 5; 
 $n  ;

Talking to the outside world

A handle represents a connection to something managed by something else, typically through "system calls".

A file handle is your connection to a file (so, managed by the filesystem or OS) but is not the file itself. With that filehandle, you can can read from or write to the file, there is code behind all that to talk to the system to do the actual work.

 open my $filehandle, '<', $filename or die "$!";

Since you are not managing the actual work and since you depend on the system to do the work, you check the $! system error variable to check that the system was able to do what you wanted. If it couldn't, it tells you how it ran into a problem (although the error may not be very specific).

A directory handle is a way to get a list of the things inside a directory, but is not the directory itself. To get that, you have to ask the system to do things for you. And so on.

Perl is wonderful though

But, in Perl, you can make a handle to anything you like (and I write a lot about this in either Effective Perl Programming and Mastering Perl. You can use the interface for a handle even if you wholly control the thing and don't need to ask the system to do something on your behalf.

For example, you can use the filehandle interface on a string:

 open my $string_filehandle, '>', \my $string;
 print {$string_filehandle} "This goes to the string";

To your code as you read it, it looks like the thing is a file (socket, whatever) because the main use of the handle interface. This is quite handy when your are handcuffed to using a filehandle because someone else wrote some code you can't change. This function is designed to only send $message to some output handle:

sub print_to_file_only {
    my( $filehandle, $message ) = @_;
    print {$filehandle} $message;
    }

But sometime you don't want that message to go to the terminal, file, socket, or whatever. You want to see it in my program. You can capture the message in your $string_filehandle because it uses the same handle interface even though it's not a static resource.

print_to_file_only( $string_filehandle );

Now you'll see the message show up in $string, and you can do whatever you like with it.

There are many more tricks like this, and I'm tempted to talk about all of them. But, this should be a good start.

CodePudding user response:

This can be a very broad topic and I'll try to stay with the crux of the question, captured in a line from IO::Pipe docs

The object is re-blessed into a sub-class of IO::Handle, and becomes a handle at the reading end of the pipe.

A "handle" in Perl is a construct built around some resource, out in the OS or in our program, which allows us to manage that resource. A filehandle, for instance, may facilitate access to a file, via libraries and OS facilities, and is more than a plain file descriptor.

use warnings;
use strict;
use feature 'say';

open my $fh, '<', $file or die "Can't open $file: $!";
say fileno $fh;   # a small integer, normally >= 3
say $fh->fileno;  # can use it as object of IO::Handle or IO::File

The opened file got a file descriptor in the OS, a small integer, the first one available. But the thing we get is the "filehandle" $fh associated with it, which is far nicer to work with and with which various tools can be used. (The fileno was used to get the fd from it.)

In newer Perls (since v5.14.0) a (file)handle can in fact be treated as an object of the class IO::Handle or IO::File, as these classes will be loaded on demand once a method call from these classes is used on the variable with the handle (if the call can't be found otherwise).

This brings us to the second question, of "re-bless"-ing.

When a reference is bless-ed "into" a package it becomes an object of (the class supposedly defined in) that package. It now "knows" that it comes from that package, one can call methods defined in the package on it, etc. This is a bit oversimplified, go read perlootut and perlobj for starters.

The quote from the docs used in the question comes from the reader or writer methods in IO::Pipe class. Once they are called on an object of that class it becomes beneficial for the object to have all the nice facilities defined in IO::Handle, so it is "made" into an object of that class. (Not to IO::File since a pipe isn't seekable while IO::File inherits from IO::Seekable as well.)

As a final comment, note that a "(file)handle" can be opened to things entirely other than an OS resource like a file/socket (etc). For example, it can be "tied" (see perltie, Tie::Handle); or, open ed to a scalar ("in-memory file").


If STDIN, STDOUT, or STDERR (fd's 0,1,2) aren't closed and this is the first thing opened, it gets 3. Etc.

The IO::File inherits from IO::Handle and IO::Seekable, adding only a few methods. Most classes that represent various handles, like IO::Pipe or IO::Select, inherit from IO::Handle.

CodePudding user response:

Most languages create variables and objects in very different ways. In Perl, they are very similar.

Perl allows most types of variables to be marked as an object by the bless functionality.

This confer additional powers to the variable to call methods in the class. Perl will search that class for a method of that name. If you fail to supply the second argument to bless, it will use the current package or class to search.

In their IO::Pipe example, you call IO::Pipe's new() method to obtain a blessed object. To them make use, they fork() and the parent converts ("re-blessed") $pipe to a reader subclass of IO::Pipe with methods calls that work as a reader. The child process converts their $pipe to a write. Now they may communicate from child to parent via the pipe.

  • Related