Take the 2-minute tour ×

I'm running 32 bit ActiveState 5.14.2 on Windows 7. I wanted to mess around with a git pre-commit hook to detect programs being checked in with syntax errors. (Somehow I just managed to do such a bad commit.) So as a test program I randomly jotted this:

use strict;
use warnings;

Syntax error!

exit 0;

However, it compiles and executes with no warnings, errorlevel is zero on exit. How is this valid syntax?

share|improve this question
I have a soft spot in my heart for Perl, but this makes me cry a little. –  JSBձոգչ Jul 28 '12 at 2:25
Perl is magic =D –  Izkata Jul 28 '12 at 4:40
Did you just prove that typing random words into perl produces working programs??!?!?!?! –  Peter M Aug 10 '12 at 19:16
@PeterM Hardly random words. I proved I don't know enough about Perl syntax. Now I know a bit more. –  Bill Ruppert Aug 12 '12 at 12:06
You probably want no indirect to stop those ones from happening –  LeoNerd 2 days ago
show 1 more comment

3 Answers

up vote 251 down vote accepted

Perl has a syntax called "indirect method notation". It allows


to be written as

new Foo $bar

So that means

Syntax error ! exit 0;

is the same as

error->Syntax(! exit 0);



Not only is it valid syntax, it doesn't result in a run-time error because the first thing executed is exit(0).

share|improve this answer
@Hassan, Think of it this way, !exit(0) can no more be a type error than !$x since neither are typed. –  ikegami Jul 27 '12 at 20:51
@Hassan, The language has types. Specifically, values have types. Operators and subs are simply not confined to returning specific types of values. This turns out to be very useful at little cost (thanks to warnings). –  ikegami Jul 27 '12 at 21:25
@Nawaz, It's actually quite popular. It's used by everyone that constructs objects in Java and C++, and a large body of Perl programmers that uses new Class and print $fh ... instead of Class->new(...) and $fh->print(...). I will grant you that it causes a weird error messages, though –  ikegami Jul 28 '12 at 14:51
@TLP, The question is cool -- a puzzle because it's interesting and the answer is obvious to few -- and well written. That's surely why the question got upvotes, which probably got it "front paged" often, which got it move upvotes. But as for why my answer got so many upvotes, I don't know. It's quite banal, though a few interesting tidbits came up in the comments. I'm guessing it's mostly spillover. In any case, I'm glad to get my first "Great Answer" badge :) –  ikegami Aug 2 '12 at 19:01
@ikegami. Congrats on the badge too. Never expected such a stir over this. Btw I greatly admire your Perl work on SO. –  Bill Ruppert Aug 2 '12 at 23:18
show 11 more comments

I don't know why, but this is what Perl makes of it:

perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
yuck syntax OK

It seems that the parser thinks you're calling the method Syntax on the error-object... Strange indeed!

share|improve this answer
That's indirect method call syntax. It's (sort of) working here because the exit(0) is evaluated first, making the program exit before it tries to pass the result to 'error'->Syntax(). –  duskwuff Jul 27 '12 at 20:29
Perl seems to assume the "indirect (object) syntax", usually used like new Class instead of Class->new(). To call the method Syntax, the exit function is executed, so the run-time error never occures. –  amon Jul 27 '12 at 20:30
Congratulations. You found a program where you need to add a semi-colon in order do get the compile to fail. –  mob Jul 27 '12 at 20:32
+1 for perl -MO=Deparse -w <filename> –  Victor Aug 1 '12 at 8:11
add comment

The reason you do not get an error is that the first executed code is


Because you did not have a semicolon on the first line:

Syntax error!

The compiler will guess (incorrectly) that this is a subroutine call with a not operator ! thrown in. It will then execute the arguments to this subroutine, which happens to be exit(0), at which point the program exits and sets errorlevel to 0. Nothing else is executed, so no more runtime errors are reported.

You will notice that if you change exit(0) to something like print "Hello world!" you do get an error:

Can't locate object method "Syntax" via package "error" ...

and your error level will be set:

> echo %errorlevel%
share|improve this answer
add comment

Your Answer


