Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

G'day learned monks,

Not that long ago, a bug against the autodie pragma (which makes subroutines and functions succeed or die) was reported here on PerlMonks.

The bug all comes down to context, and how subroutines report failure, and is best shown with an example:

use File::Copy qw(copy); use autodie qw(copy); copy($foo, $bar); # Void context, succeeds or dies. my $x = copy($foo, $bar); # Scalar context, succeeds or dies. my @x = copy($foo, $bar); # Array context, succeeds or fails silently.

Our problem is that the copy subroutine always uses return 0; to indicate failure. In a scalar context this is false, and autodie assumes it means an error. However in a list context it returns (0) (a list of a single zero), which looks like something which may be a legitimate value, and so autodie passes it through fine. By default, autodie only thinks a failure has occured if it sees an empty-list, or a list consisting of a single undef.

As this example shows, autodie can fail to detect failure when it occurs in unexpected ways. The solution is to provide a hinting mechanism, where not only can a subroutine be made autodying, but hints can be provided to control to describe what it considers to be a failure.

To keep the autodie interface clean, and to ensure nobody has to repeat themselves, these hints are provided out-of-band. So when you see a piece of code like:

use File::Copy qw(copy); use autodie qw(copy);

autodie will look up the hints table for File::Copy::copy and check to see which conditions indicate failure. A table of these hints for common modules will be included in the next autodie release, but they can also be supplimented by your own code (eg: use my::autodie::hints), or even built into exporting modules themselves. This all works right now on the hints branch of the source code repository.

Most of the time, end-users will never have to worry about the hinting interface, it's only something that myself, or module developers, or very eager people will be using. Having said that, I want to make sure I get it right.

Right now, the current hinting interface sucks. You have to do something like:

use Some::Module qw(foo); use autodie::hints qw( LIST_EMPTY_ONLY SCALAR_UNDEF_ONLY ); autodie::hints->set_hints_for( \&foo, LIST_EMPTY_OR_FALSE | SCALAR_UNDEF_ONLY );

Note that we're OR'ing bits together manually to set the hints. That was due to an old idea that came to me on a coffee-deprived tram ride, and which didn't work out. Note that we're also including some big ugly constants just to use them in a single call. I don't like that at all.

So, I'd like to replace the interface. Currently the plan is to have something like this:

use Some::Module qw(foo); use autodie::hints; autodie::hints->set_hints_for( \&foo, qw( LIST_EMPTY_OR_FALSE SCALAR_UNDEF_ONLY ) );

Here we're passing in a list of strings as hints, which makes error messages nicer (you typed X, did you mean Y?), and avoids having to screw around with bitwise operations. Settings currently have the first word being the context they apply to (scalar/list), and then we list what are considered 'failure' values. The current list are as follows:

  • SCALAR_ANY_FALSE (default)
  • SCALAR_UNDEF_ONLY
  • LIST_EMPTY_OR_UNDEF (default)
  • LIST_EMPTY_ONLY
  • LIST_EMPTY_OR_FALSE

Note that there are some things which are missing from the list, my goal is to have autodie work with the most common legacy ways of signalling errors, not every possible wacky scheme imaginable. Also note that the hinting mechanism will never be used for Perl's built-in functions, autodie is already aware of their special cases, and no further user intervention is necessary.

So, my question to you, dear monks, is can I do this better? Can the hints be given better names? Is my set_hints_for method particularly unintuitive? How would you expect this to work?

The autodie module is going into the 5.10.1 release of Perl, and as such if I screw things up, it's likely they'll stay screwed for a long time. Any comments, feedback, or questions are appreciated.

Many thanks,


In reply to RFC: User subroutine hinting interface for autodie by pjf

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (2)
As of 2024-04-25 20:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found