Over the years I've learned a number of programming languages on my own, including Perl. One learning tool I figured out is to use some sort of language reference to avoid the frustration of working through several chapters in a manual just to figure out a starting point.
Another good learning trick is to find a Perl program that does something similar to what you want to do, then play with it to gradually modify its behavior, using your reference when you get stuck. Eventually you become able to start from scratch after you've formulated some idea of what you want to do, and then translate that into a set of programming instructions.
A few years ago, while in the process of a collaboration for writing a manual for Scribus, I was spending quite a bit of time on freenode.net on the Scribus channel and talking to my German collaborator and others who mostly lived somewhere in Europe. You end up having a lot of conversations about all sorts of topics, and anywhere in the world you talk about the weather, but of course they're talking Celsius temperatures while I'm experiencing Fahrenheit. So I made a little utility in Perl to see what 14 °C is, or maybe instead of telling them my weather in °F, I'd be able to give them a number in °C.
Let's use this to talk a bit about Perl.
#!/usr/bin/perl -w
print "\nThis is the program for Fahrenheit to Celsius\n
and Celsius to Fahrenheit temperature conversion\n\n";
$temp = $ARGV[0];
$f1temp = $temp . "°F";
$ctemp = ($temp - 32)* 5.0/9.0;
$rtemp = sprintf("%.1f", $ctemp);
$c1temp = $rtemp . "°C";
print "$f1temp is $c1temp\n\n";
$ftemp = $temp* 9.0/5.0 + 32;
$rtemp = sprintf("%.1f", $ftemp);
$c2temp = $temp . "°C";
$f2temp = $rtemp . "°F";
print "$c2temp is $f2temp\n\n";
I named this tempconv.pl
, so the first thing to point out is that you name a file with a .pl
extension to indicate that this is a Perl script. Next, look at the first line. It begins with these characters: #!
This has a name, shebang, after which it's telling your computer where to find the interpreter, and the -w
is asking for warnings about mistakes I may have made while writing this script. This line has to be the first line of the script.
The second line is just a little message to myself to confirm what this is doing, and of course not only is this part of the output, but I can read this when I look at the file, so in this case it is the full extent of the documentation for this script. This \n
you see repeatedly is to have the printout (onscreen in this case) add a newline, or carriage return. It's easier to read if you break the output up a bit. I used double quotes, which behave differently from single quotes. For example the \n
inside single quotes is printed literally; it is not interpreted and does not create a new line.
The third line finally gets to the meat of what we want to run this for. Notice all these words or word fragments beginning with $
. All variable names must begin with a special character. The $
indicates a scalar variable, or in other words, a variable with a single value. ARGV
is a special variable name used by Perl to refer to any input sent to the script when the program is run.
I could in fact have entered several numbers, tempconv.pl 45 23 38
, in which case these three values create an array, @ARGV
, from which we might specify $ARGV[0]
, which would be 45, or $ARGV[1]
for 23, and so on. As this script is written it won't matter how many values you include, since it's only going to use the first value. (We'll get back to this later.)
To convert a temperature, type tempconv.pl 45
to convert the value 45. ARGV
refers to that input, 45.
Next, some interesting things happen. Notice how I assign a string value of 45 °F
to the variable $f1temp
(the period is a concantenation operator to glue these two together). In the next line, I take the same input and perform mathematical operations with it. So was 45 a string or a number? Both, obviously. You should be able to recognize the formula for conversion of a Fahrenheit temperature to Celsius in ($temp - 32)*9.0/5.0
.
All that's left is to print the result, but I want to make sure this comes out as a floating point number with one decimal place, that's what the sprintf
command is doing.
The remainder of this script simply assumes that the 45 was in Celsius and converts to Fahrenheit, so in total the output of this script is:
This is the program for Fahrenheit to Celsius and Celsius to Fahrenheit temperature conversion 45°F is 7.2°C 45°C is 113.0°F
It may seem odd I would do this, but what happened was that originally I made two scripts, one named celsius.pl
and the other fahren.pl
, and each only did one calculation. The problem was that after some time went by, I forgot whether celsius.pl
wanted a Celsius value or it was making one. It seemed to me the simplest thing was to just combine the operations, give both answers and keep usage simple. To further the simplicity, I also created an alias to run in Bash, called temp
, which saves typing not only the entire filename, but also the path to it.
A not so difficult addition would be to create a loop, so that more than one value might be entered, and serial calculations take place. The main consideration is to detect how many values have been entered to avoid generating errors. More importantly, I haven't seen the need for this. But let's mention at this point a feature of Perl you may have noticed, which is that each line ends in a semicolon except for the first one. I should qualify that by saying that each executable statement ends with a semicolon. For example, let's say we wanted to add an optional message at the end based on a conditional:
if ($rtemp > 99) {
print "Wow! That's hot!\n\n";
}
The executable part still ends with a semicolon, but the if conditional has its own structure, using curly brackets to corral all the lines that will be executed if the condition is met. Typically these are indented so they stand out more easily when you read the script.
It's easy enough to imagine taking what you see here and making various other little utilities to convert weights, distances, typographic measurements, and so on, and in fact I've done a number of these.
9 Comments