IO-Die

 view release on metacpan or  search on metacpan

lib/IO/Die.pm  view on Meta::CPAN

        #...something that sets an internal coderef “_create_err_cr”
    }

    sub _CREATE_ERROR {
        my ( $self, $type, %args ) = @_;
        return $self->{'_create_err_cr'}->($type, %args);
    }

    MyDynamicIO->sysopen( .. );     #uses “_create_err_cr” above

=head1 DETAILS

This module wraps most of Perl’s built-in I/O functions with code that
throws exceptions if the requested operation fails.
It confers many of C<autodie>’s benefits but with some distinctions
from that module that you may appreciate:

* C<IO::Die> does not overwrite Perl built-ins.

* C<IO::Die> does not clobber globals like $! and $^E.

* C<IO::Die> does not use function prototypes and does not export:
all calls into C<IO::Die> (or subclasses) “look like” what they are.

* C<IO::Die> does not try to impose its own error handling; you can customize
both how to represent errors and what to do with them.

* C<IO::Die> seems lighter than C<autodie> in simple memory usage checks. YMMV.

For the most part, you can simply replace:

    read( ... );

...with:

    IO::Die->read( ... );

This module, though, explicitly rejects certain “unsafe” practices that Perl
built-ins still support. Neither bareword file handles nor one-/two-arg
C<open()>, for example, are supported here--partly because it’s more
complicated to implement, but also because those patterns seem best avoided
anyway. Damian Conway’s “Perl Best Practices” and the present author’s
experience largely inform discernment of the above, which is admittedly
subjective by nature.

This module also rejects use of a single Perl command to operate on multiple
files, as e.g. Perl’s C<chmod()> allows. This is because that is the only
way to have reliable error checking, which is the whole point of this module.

Finally, since this doesn’t use function prototypes, some of the syntaxes
that Perl’s built-ins support won’t work here. You’ll likely find yourself
needing more parentheses here.

The intent, though, is that no actual functionality of Perl’s built-ins
is unimplemented; you may just need to rewrite your calls a bit
to have this module perform a given operation. For example:

    open( GLOBALS_R_BAD, '>somefile' );
    IO::Die->open( my $good_fh, '>', 'somefile');

    chown( $uid, $gid, qw( file1 file2 file 3 ) );
    IO::Die->chown( $uid, $gid, $_ ) for ( qw( file1 file2 file3 ) );

    print { $wfh } 'Haha';
    IO::Die->print( $wfh, 'Haha' );

(And, yes, unlike C<autodie>, C<IO::Die> has a C<print()> function!)

Most Perl built-ins that C<autodie> overrides have corresponding functions in this module.
Some functions, however, are not implemented here by design:

* C<readline()> and C<readdir()>: Perl’s built-ins do lots of "magic" (e.g.,
considering '0' as true in a C<while()>) that would be hard to implement.

* C<system()>: This one does a lot “under the hood”, and it’s not feasible
to avoid clobbering global $? if you use it.

* C<tell()> doesn’t write to $! and so can’t be error-checked.

* C<printf()> seems not to have much advantage over combining C<print()>
and C<sprintf()>. (?)

Some functions are thus far not implemented, including C<write()>, C<ioctl()>,
C<syscall()>, semaphore functions, etc. These can be implemented as needed.

=head1 PRELOADING

As of version 0.057, this module only loads in a stub at first; each I/O
method that you call from this module is then lazy-loaded. This is meant to
make this module use the least amount of memory possible.

If you want to load everything all at once (as 0.056 and prior versions did),
pass the C<:preload> tag when you C<use()> this module, e.g.:

    use IO::Die qw(:preload);

=head1 FUNCTIONS THAT DIFFER SIGNIFICANTLY FROM THEIR PERL BUILT-INS

The following are not complete descriptions of each function; rather,
this describes the B<differences> between the relevant Perl built-in and
C<IO::Die>’s wrapper of it. It is assumed that the reader is familiar
with the built-in form.

Note that NONE of the following functions support bareword filehandles.

=head2 open()

This supports all built-in forms of 3 or more arguments. It ONLY supports
the two-argument form when the second argument (i.e., the MODE) is “|-” or “-|”.

=head2 select()

Only the four-argument form is permitted.

=head2 chmod()

=head2 chown()

=head2 kill()

=head2 unlink()

=head2 utime()

Unlike Perl’s built-ins, these will only operate on one filesystem node at a time.
This restriction is necessary for reliable error reporting because Perl’s
built-ins have no way of telling us which of multiple filesystem nodes produced
the error.

=head2 exec()

This always treats the first argument as the program name, so if you do:

    IO::Die->exec('/bin/echo haha');

… that will actually attempt to execute a program named C<echo haha> in the
directory C</bin>, which probably isn’t what you wanted and will thus fail.
(In the above case, what was likely desired was:

    IO::Die->exec('/bin/echo', 'haha');

=head1 CONVENIENCE FUNCTIONS

=head2 systell( FILEHANDLE )

This function returns the unbuffered file pointer position.

=head1 FUNCTIONS THAT LARGELY MATCH THEIR RELEVANT PERL BUILT-INS

The remaining functions intend to match their corresponding Perl built-ins;
differences should be regarded as bugs to be fixed!

=head1 CUSTOM ERROR HANDLING

C<IO::Die>’s default error format is a rather primitive one that just
consists of the error parameters in a string. By default, this error is
thrown via Perl’s C<die()> built-in. If you need more
robust/flexible error handling, subclass this module, and override the
C<_CREATE_ERROR()> and/or C<_DO_WITH_ERROR> methods.

C<_DO_WITH_ERROR()> receives these parameters:

* The namespace

* The error (i.e., the error as returned by C<_CREATE_ERROR()>)

C<_CREATE_ERROR()> receives these parameters:

* The namespace.

* A name for the error type, e.g., “FileOpen”.

* A list of key/value pairs that describe the error.

The error types are proprietary to this module and listed below.

=head1 PROPRIETARY ERROR TYPES



( run in 0.586 second using v1.01-cache-2.11-cpan-71847e10f99 )