No semicolon after return values

Perl lets you omit semicolons at the end of a block. That is, you can treat ; as a statement separator, not a terminator, as in Pascal.

OK, but why would you want to do that? The advantage of terminating each statement is that you don't need to do anything special for the first and last lines: You can insert or remove lines at any point without worrying about the rest of the code. Why throw that away?

Because sometimes it doesn't make sense to add code at the end. Consider this code:

sub foo {
  my ($s) = @_;
  $s =~ s/%/%%/g;
  $s
}

The last statement $s is the return value. Adding statements after it could silently break this function. By omitting the last semicolon I can make the code a bit more robust, because now I get a syntax error when I try to put more code at the end without paying attention.

Maybe you don't use this form of code, though. Maybe you always write an explicit return. In that case any following code is silently ignored, so in the above scenario you wouldn't break anything, but your changes wouldn't have any effect either.

And there's another case that affects everyone who writes modules. Files loaded by require (directly or indirectly via use) need to return a true value. Most people simply write 1; at the end of their modules. I think it makes sense to omit the ; here as well, because nothing should come after it.

I've actually seen people cargo-cult module code, putting 1; in the middle of their Perl files. For those people: 1; doesn't make sense unless it's the last statement in a file and that file is a module. Everyone: you should end your modules with 1, not 1;.

(That's what I think, anyway. I hope this posting makes some sense.)

6 Comments

You should use the:

return $s;

Yours is hard to parse because my brain is going to go "what is wrong with that statement?" and not think "$s is the return".

Don't do it.

If you're a programmer and you add code after

{
...
return $s;
}

without noticing, you do not need to be a programmer. :)

I used to use the statement without explicit return for constants and subroutines which has error message as their return value.

sub readOnly ( $; ) { shift->read_write }

or

sub validate ( $;$ ) {
my $error;
...
$error; # but which semicolon appended
}

but I couldn't recommend it for any other uses otherwise many people who is not accustomed to perl will be confused. (-:

Acme::ReturnValue might give you a few ideas beyond 1, not 1;

Although I see the point, I believe in keeping a constant style throughout your code, so if you end all your statements with ';' this should be consistent with all statements.

This is the same problem I have with languages like JavaScript which allow you to do things like:

if( true ){
//something
}


and


if(true)
//something


If you decide in a way to do it, you should stick to it, otherwise it can generate confusion in the long term.

Interesting thought. I personally always add a semicolon for the last statement of the block (though I also seldom use explicit 'return'). Unless they are inline, e.g.:

for (...) { stmt; last-stmt }

Dunno. These are just habits, I guess.

Leave a comment

About mauke

user-pic I blog about Perl.