> Functions like stat() and get*ent() return long lists of mysterious
> values.  The implementation is assumedly easy: just push some values
> out of C structs into the Perl return stack.
 . . .
> Firstly, who can remember which one of the stat() return values was
> the atime is or which is the 4th return value of localtime()?  The
> perlfunc documentation makes this difficulty painfully obvious by
> having to list the indices alongside the values.

I must respectfully disagree.  The following line of code was
written by doing `man perlfunc', a few keystrokes to find the
right instance of `  stat ', and a cut and paste:

($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
                    $atime,$mtime,$ctime,$blksize,$blocks)
                                            = stat($filename);

For everyone who knows they need to make a stat() call, that
line tells them everything they need to know.

A few more keystrokes changes it to

    (undef,undef,undef,$nlink) = stat($filename);

which informs the reader than yes, the program really meant to throw
away everything else from the stat call.  In a well-optimised
compiler, it would even pass only the one data element actually used.

Returning pre-parsed lists is a win, especially if one needs some
large subset of the values returned.  I use this feature regularly,
and would not wish to see it go away.

> Secondly, the current solution is seriously non-extensible.  One
> cannot easily add new return values to the APIs because someone may be
> expecting an exact number of return values, or someone may be
> accessing the values by position from the end of the list Obsoleting
> values (or marking them as non-applicable to the current platform) has
> to be done by for examples returning undef.

The above is a more telling criticism, but I that `stat()' is a
poor example -- it's not likely to change much.  I'm sure there are
better, but have not bothered to look.  :-)

> =head1 IMPLEMENTATION

I strongly support Damiens suggestion on a hashref, and would go so
far as to say it should be a pseudo-hash, with all the attendant
misspelling protections and speed obtained.

Passing lists around can be expensive, manipulating hashes can be
expensive.  I'd extend Damiens suggestion to allow the programmer
to specify only the sub-data desired, eg:

    # undef context, store results in passed hashref

    my %data_wanted = \(mode => 0, nlink => 0);
    stat( $filename,\$data_wanted);

This could even be done in a list context, with a possible
implementation suggested:

    # List context, return only the two values requested in order

    ($mode,$nlink) = stat($filename,\('mode','nlink'));

Reply via email to