Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Matts (1087)

  (email not shown publicly)

I work for MessageLabs [] in Toronto, ON, Canada. I write spam filters, MTA software, high performance network software, string matching algorithms, and other cool stuff mostly in Perl and C.

Journal of Matts (1087)

Saturday October 28, 2006
09:24 PM

The case of the stupid API

[ #31439 ]

AKA - Annoyed by default return

Perl sometimes annoys me.

A couple of weeks ago it was the fact that a my variable declared in a if (...) block is still valid in the same block's elsif (...) section, meaning that you get warnings if you do:

if (my $val = $tiedhash{$key}) {
elsif (my $val = $othertiedhash{$key}) {

This vexxed me greatly.

Today I was bugged by a combination of my own bad API and perl's decision to make the last value in a sub be the return value,

Frankly if I don't specifically return anything, I would rather any return value be ignored. Or I wish there were a "use strict 'return'" which would turn off this ugly behaviour.

My API was a network socket API, which if I returned a value from "sub process_line" it would send that back as a response. I forgot about the return value and instead wrote my own response to the socket.

But by the magic of perl's default return value, I got my $self->{status} value written to the socket.

Thank god for tcpdump. It truly saved the day by seeing what exactly I was writing to the socket, and reminded me about my dumb API.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Perl::Critic [] can help here. There is a plugin called Perl::Critic::Policy::Subroutines:RequireFinalReturn that checks your code and ensures that every subroutine ends with an explicit return (or die, goto, croak or exit).
  • I get a lot of milage out of implicit return – I write many functions that consist of a single expression (disregarding parameter parsing), which read much nicer that way.

    Maybe precisely because I use it so purposefully, I am always keenly aware that subs always return something, and so when writing subs that aren’t supposed to, I usually put a bare return in there.

    • I do this too, as can be seen in my code on CPAN. I just would like a strict mode to turn it off.
  • Aren't those Perl rules? I know that last statement is the return by default is covered in "Learning Perl", so I guess I always have that in my head. The IF statement doesn't bother me as I look at those as blocks.
    • As I said, it was partly due to the dumb API, but often times the last statement is hidden somewhere in an if block, or while block or something. I think I'd personally rather have an explicit return, via use strict 'return';
      • I think I'd personally rather have an explicit return, via use strict 'return';

        I get what you are saying now.

  • It's the fact that return value of blocks is the last expression evaluated. And the body of a subroutine is a block.

    The fact that blocks return the last expression evaluated is what makes writing concise maps and greps.

    Also note that whether a subroutine returns something or not is not determined by a return, or a last expression. Like anything else, it's determined by context. A subroutine will return nothing, if, and only if, it's called in void context. Otherwise, it will return something, even if it

    • It's an OO API, so you subclass process_line to process a line of data. But I forgot that (somewhere in another file/class) that if process_line returns a scalar it gets sent to the client. It's hard to see that sort of thing in OO virtual APIs sometimes, but as everyone has rightly pointed out - it was programmer error.

      Doesn't mean I think "use strict 'return'" is any less of a good idea though.
    • I've been bitten by this in mod_perl handlers. I forgot to return OK, and the final statement was returning undef. That triggered a "Use of uninitialised value" message in the error log... but it had no line number info. That took me months to track down. I've always been very explicit about using return since then.