Constants Again

Do you ever write programs that use constants? You probably do without knowing it. The canonical example is a geometry program that uses the special number π (pi):

  my $area = 2 * 3.14159 * $radius;

But what if you have multiple parts of your program where you have to put the value, and maybe you mistype it in one place, or use the wrong number of digits? So you put it in a variable at the top of your program:

  my $pi = 3.14159;
  ...
  my $area = 2 * $pi * $radius;

That’s fine. But what if you accidentally modify the value of $pi? It’s not so hard as you think. Consider this buggy line of code. The programmer wanted to compare the value of $pi to the formula, but used = instead of == by mistake:

  if ($pi = $x / ( 2 * $radius ))
  {
      print "$x is the area\n";
  }

OK, so it’s a contrived example. But the point is, it’s not hard to accidentally modify a variable when you mean to compare its value. If $x isn’t actually the area, then you now have an incorrect value of $pi! And as long as $x and $radius are nonzero, the print statement will always be executed!

To avoid this we use a constant instead. These are easy to do in Perl:

  use constant PI => 3.14159;
  ...
  my $area = 2 * PI * $radius;

Now if your program tries to modify π it’s an error! Why? Well technically, "use constant" creates a subroutine, not a variable. The subroutine PI() returns 3.14159. But Perl doesn’t require the parentheses so you can just say PI by itself.

Perhaps you are thinking now that subroutines cause too much overhead, so this is a bad idea. Well, Perl takes care of that issue too. There’s an optimization for any subroutine that just returns a constant value (i.e., there are no variables or other subroutine calls in it). It’s "inlined" which means that it is as if you had typed "3.14159" instead of PI in the formula. So it’s even faster than a variable at runtime!

Perhaps you don’t do a lot of math in your programs. Here are some other uses for constants:

  • Names of files that are accessed in several places but where the filename does not change.
      use constant FILENAME => "myprogram.conf";
  • Identifiers used when connecting to a database to look up a particular row of a table.
      use constant PERL_ID => 42;
  • Strings or numbers that have little meaning to the human eye but have particular meaning inside your program.
      use constant FILE_READABLE   => 4;
      use constant FILE_WRITEABLE  => 2;
      use constant FILE_EXECUTABLE => 1;
      ...
      my $stat = FILE_READABLE | FILE_EXECUTABLE;     # bitwise OR

One caveat: remember that "use" statements are run when Perl starts up, not when the script is being executed.

2 Responses to “Constants Again”

  1. Andy says:

    I know it doesn’t matter for the point you’re making but I feel obliged to inform you that for a circle, 2 * PI * $radius is the circumference vs PI * $radius ** 2 is the area.
    (-:

  2. William Ward says:

    I put that in there to see if anyone was really paying attention. Yeah, that’s the ticket! *blush*

Leave a Reply