Rabu, 05 Mei 2010

So is wantarray() bad or not?

The style of returning different things in list vs scalar context has been debated for a long time (for a particular example, this thread in Perlmonks).

A few months ago I made a decision that all API functions in one of my projects should return this:

return wantarray ? ($status, $errmsg, $result) : $result;

That is, we can skip error checking when we don't want to do it.

Now, in the spirit of Fatal and autodie, I am changing the above to:

return wantarray ? ($status, $errmsg, $result) :
do { die "$status - $errmsg" unless $status == SUCCESS; $result };


But somehow I can still see myself and others tripping over this in the future, as I have, several times so far. It's bad enough that for each API function one already has to remember the arguments and their types, and one kind of return and its type.

Maybe I should just bite the bullet and admit the misadventure into wantarray(), and that context-sensitive return should be left to @foo, localtime(), and a few other classical Perl 5 builtins that have been ingrained in every Perl programmer's mind.

2 komentar:

  1. Personally this this kind of thing is going to cause you headaches. DBIx::Class overloaded ->resultset via wantarray to either return an object or an array and its one of the choices most regretted.

    wantarray I think is something like goto, if you need it you really need it, but I don't make using it a habit

    BalasHapus
  2. @john: Thanks for the comment. I agree, we really need to think several times before using wantarray(). That said, I am still somewhat leaning towards it.

    I have two use cases: first, API function calling another API function. Second, application code calling API function.

    API function code are generally more well thought out, more carefully designed, coded, and tested. They will almost always use the array form:

    ($status, $errmsg, $result) = API::func($args);

    While application code might or might not do this. They might just say:

    $result = API::func($args);

    I think it's a great idea to help (or punish?) the last case, i.e. automatically dying with $status and $errmsg whenever $status is not a successful code.

    This can be done with or without wantarray() though.

    BalasHapus