Examining Exit Codes of 4 simple programs with bugs: Python, Ruby, Perl, PHP

Strict type checking is an aspect of the compiler to make sure that your programs have properly declared all of the necessary variable names prior to their use. I believe it is essential to all modern languages to implement proper errors in the event that an undefined variable is used. Let’s look at 4 popular scripting languages to see how they handle this problem.

For each program, we will examine three things: the source code, the execution, and the returned exit code. In modern operating systems, a program that concludes execution successfully returns a code of 0. If any problems arise in the course of the program, it should return something other than 0. I used the UNIX command “echo $?” to check the exit code.

All 4 programs will print the word “Hi” to the screen, then it will try to print an undefined variable “thisDoesNotExist”. After that, it will print “Hi again”. We would hope that the program will abort some time during the execution of the program and tell us that “thisDoesNotExist” is undefined. We would also hope that the program would never return an exit code of 0.

First, my favorite little language: Python

badName.py:

print "Hi"
print thisDoesNotExist
print "Hi again"

Execution and return code:

jcchurch@mccarthy:~/tmp/exitCodes$ python badName.py
Hi
Traceback (most recent call last):
  File "badName.py", line 2, in <module>
    print thisDoesNotExist
NameError: name 'thisDoesNotExist' is not defined
jcchurch@mccarthy:~/tmp/exitCodes$ echo $?
1

Python gives me a good error message “NameError: name ‘thisDoesNotExist’ is not defined”. It also returns a status code of 1. This is what we should expect from a modern language.

Second: Ruby

badName.rb:

puts "Hi"
puts thisDoesNotExist
puts "Hi again"

Execution and return code:

jcchurch@mccarthy:~/tmp/exitCodes$ ruby badName.rb
Hi
badName.rb:2: undefined local variable or method `thisDoesNotExist' for main:Object (NameError)
jcchurch@mccarthy:~/tmp/exitCodes$ echo $?
1

Ruby also gives a good error message “undefined local variable or method `thisDoesNotExist’” and an exit code of 1.

Third: Perl

Not every language designer agrees with me that strict type checking is essential. Perl requires us to use the statement “use strict;” to use strict type checking. I wish this were turned on by default.

badName.pl:

use strict;

print "Hi\n";
print $thisDoesNotExist;
print "Hi again\n";

Execution and return code:

jcchurch@mccarthy:~/tmp/exitCodes$ perl badName.pl
Global symbol "$thisDoesNotExist" requires explicit package name at badName.pl line 4.
Execution of badName.pl aborted due to compilation errors.
jcchurch@mccarthy:~/tmp/exitCodes$ echo $?
255

Perl doesn’t even print “Hi”. It gives the error message “Global symbol “$thisDoesNotExist” requires explicit package name”, which is a tad cryptic, but it does the job we want it to do. It also returns with a exit code of 255.

Fourth: PHP

I’m breaking my rule of never posting PHP code on this site. Like Perl, strict type checking is turned off by default. We can turn it on with the statement “error_reporting(E_ALL);”.

badName.php:

<?
error_reporting(E_ALL);
print "Hi\n";
print $thisDoesNotExist;
print "Hi again\n";
?>

Execution and return code:

jcchurch@mccarthy:~/tmp/exitCodes$ php badName.php 
Hi

Notice: Undefined variable: thisDoesNotExist in /home/jcchurch/tmp/exitCodes/badName.php on line 4
Hi again
jcchurch@mccarthy:~/tmp/exitCodes$ echo $?
0

PHP gives us a good error message: “Undefined variable: thisDoesNotExist”. But wait! It keeps going! We see “Hi again” AFTER the error message, which means this isn’t really an error message but a warning. When the program concludes, the exit code returned to the operating system is 0, which tells me that nothing went wrong in the program.

Conclusion

Python and Ruby demonstrate the same behavior: Execute as much of the program as possible until an error is reached. Once the error is reached, print an error and abort the program.

Perl compiles the entire program and notices the undefined variable at compile time. It prints the error without executing any of the code.

PHP executes as much of the code as possible. When it encounters the undefined variable, it happily prints a warning message and keeps on going. Finally, it tells us that there were no problems in the code with an exit code of 0.

Oh PHP. Maybe you will grow up as a language one of these days.

  1. jenni-henry reblogged this from jcchurch
  2. java-oracle-programacion reblogged this from jcchurch
  3. jcchurch posted this