Playing With Mud
In the first part of this tutorial, we introduced you to the basics of Perl, Austin Powers-style. This week, we’re going to get down and dirty with variables and operators, and also provide you with a brief introduction to Perl’s conditional expressions.
To begin with, let’s answer a very basic question for all those of you unfamiliar with programming jargon: what’s a variable when it’s at home?
A variable is the fundamental building block of any programming languages. Think of a variable as a container which can be used to store data; this data is used in different places in your Perl program. A variable can store both numeric and non-numeric data, and the contents of a variable can be altered during program execution. Finally, variables can be compared with each other, and you - the programmer - can write program code that performs specific actions on the basis of this comparison.
Every language has different types of variables - however, for the moment, we’re going to concentrate on the simplest type, referred to in Perl as “scalar variables”. A scalar variable can hold any type of value - integer, text string, floating-point number - and is usually preceded by a dollar sign.
The manner in which scalar variables are assigned values should be clear from the following example:
#!/usr/bin/perl
# a simple scalar variable
$name = "mud";
# and an example of how to use it
print ("My name is ", $name);
And here’s what the output of that program looks like:
$ My name is mud
Really?! We feel for you…
It shouldn’t be too hard to see what happened here - the scalar variable $name was assigned the text value “mud”, and this value was then printed to the console via the print() statement.
Although assigning values to a scalar variable is extremely simple - as you’ve just seen - there are a few things that you should keep in mind here:
-
A scalar variable name must be preceded by a dollar [$] sign - for example, $name, $id and the like. This helps differentiate between scalar variables and arrays or hashes, which are the other types of variables supported by Perl.
-
Every scalar variable name must begin with a letter, optionally followed by more letters or numbers - for example, $a, $data123, $i_am_god
-
The maximum length of a scalar variable name is 255 characters; however, if you use a name that long, you need therapy!
-
Case is important when referring to scalar variables - in Perl, a $cigar is definitely not a $CIGAR!
-
It’s always a good idea to give your variables names that make sense and are immediately recognizable - it’s easy to tell what $gross_income refers to, but not that easy to identify $ginc.
-
Unlike other programming languages, a scalar variable in Perl can store both integers and floating-point numbers [also known as decimals]. This added flexibility is just one of the many nice things about Perl.
Here’s another program, this one illustrating how variables can be used to store and manipulate numbers.
#!/usr/bin/perl
# declare a variable
$number = 19;
print ($number, " times 1 is ", $number,"\n");
print ($number, " times 2 is ", $number * 2, "\n");
print ($number, " times 3 is ", $number * 3, "\n");
print ($number, " times 4 is ", $number * 4, "\n");
print ($number, " times 5 is ", $number * 5, "\n");
And here’s what the output looks like:
$
19 times 1 is 19
19 times 2 is 38
19 times 3 is 57
19 times 4 is 76
19 times 5 is 95
$
Q&A
Thus far, you’ve been assigning values to your variables at the time of writing the program itself [referred to in geek lingo as “design time”]. In the real world, however, many variables are assigned only after the program is executed [referred to as “run time”]. And so, this next program allows you to ask the user for input, assign this input to a variable, and then perform specific actions on that variable.
#!/usr/bin/perl
# ask a question...
print "Gimme a number! ";
# get an answer...
$number = <STDIN>;
# process the answer...
chomp($number);
$square = $number * $number;
# display the result
print "The square of $number is $square\n";
If you try it out, you’ll see something like this:
$
Gimme a number! 4
The square of 4 is 16
$
Let’s go through this in detail. The first line of the program prints a prompt, asking the user to enter a number. Once the user enters a number, that input is assigned to the variable $number via the <STDIN>
file handler. This particular file handler allows you to access data entered by the user at the command prompt, also referred to as STanDard INput.
At this point in time, the variable $number contains the data entered by you at the prompt, together with a newline [\n] character [caused by you hitting the Enter key]. Before the number can be processed, it is important that you remove the newline character, as leaving it in could adversely affect the rest of your program. Hence, chomp().
The chomp() function’s sole purpose is to remove the newline character from the end of a variable, if it exists. Once that’s taken care of, the number is multiplied by itself, and the result is displayed. Note our slightly modified usage of the print() function in this example - instead of using parentheses, we’re simply printing a string and replacing the variables in it with their actual values.
2 + 2 …
As you’ve already seen in last time’s lesson, Perl comes with all the standard arithmetic operators - addition [+], subtraction [-], division [/] and multiplication [*] - and quite a few non-standard ones. Here’s an example which demonstrates the important ones:
#!/usr/bin/perl
# get a number
print "Gimme a number! ";
$alpha = <STDIN>;
# get another number
print "Gimme another number! ";
$beta = <STDIN>;
# process input
chomp($alpha);
chomp($beta);
# standard stuff
$sum = $alpha + $beta;
$difference = $alpha - $beta;
$product = $alpha * $beta;
$quotient = $alpha / $beta;
# non-standard stuff
$remainder = $alpha % $beta;
$exponent = $alpha ** $beta;
# display the result
print "Sum: $sum\n";
print "Difference: $difference\n";
print "Product: $product\n";
print "Quotient from division: $quotient\n";
print "Remainder from division: $remainder\n";
print "Exponent: $exponent\n";
As with all other programming languages, division and multiplication take precedence over addition and subtraction, although parentheses can be used to give a particular operation greater precedence. For example,
#!/usr/bin/perl
print(10 + 2 * 4);
returns 18, while
#!/usr/bin/perl
print((10 + 2) * 4);
returns 48.
In addition to these operators, Perl also comes with the very useful auto-increment [++] and auto-decrement [–] operators, which you’ll see a lot of in the next lesson. For the moment, all you need to know is that the auto-increment operator increments the value of the variable to which it is applied by 1, while the auto-decrement operator does exactly the same thing, but in the opposite direction. Here’s an example:
#!/usr/bin/perl
# initial value
$a = 7;
print("Initial value: ", $a, "\n");
# increment and display
$a++;
print("After increment: ", $a, "\n");
… Or Two Plus Two
Of course, operators are not restricted to numbers alone - there are a couple of useful string operators as well. The string concatenation operator [.] is used to concatenate strings together, as in the following example:
#!/usr/bin/perl
$a = "The";
$b = "Incredible";
$c = "Shrinking";
$d = "Violet";
$result = $a . $b . $c . $d;
print "Here's one possibility - $result\n";
$result = $c . $a . $b . $d;
print "And here's another - $result\n";
And the string repetition operator[x] is used to repeat strings a specific number of times - take a look:
#!/usr/bin/perl
$a = "Loser!\n";
$insult = $a x 7;
print($insult);
Talk about using your powers for evil…
Comparing Apples And Oranges
In addition to the various arithmetic and string operators, Perl also comes with a bunch of comparison operators, whose sole raison d’etre is to evaluate expressions and determine if they are true or false. Here’s a list - you should use these operators for numeric comparisons only.
Assume $x=4 and $y=10
Operator | What It Means | Expression | Evaluates To |
---|---|---|---|
== | is equal to | $x == $y | False |
!= | is not equal to | $x != $y | True |
> | is greater than | $x > $y | False |
< | is less than | $x < $y | True |
>= | is greater than/equal to | $x >= $y | False |
<= | is less than/equal to | $x <= $y | True |
If, however, you’re planning to compare string values, the two most commonly used operators are the equality and inequality operators, as listed below.
Assume $x=”abc”, $y=”xyz”
Operator | What It Means | Expression | Result |
---|---|---|---|
eq | is equal to | $x eq $y | False |
ne | is not equal to | $x ne $y | True |
You can also the greater- and less-than operators for string comparison - however, keep in mind that Perl uses the ASCII values of the strings to be compared when deciding which one is greater.
Assume $x=”m”, $y=”M”
Operator | What It Means | Expression | Result |
---|---|---|---|
gt | is greater than | $x gt $y | True |
lt | is less than | $x lt $y | False |
ge | is greater than or equal to | $x ge $y | True |
le | is less than or equal to | $x le $y | False |
The reason for this - the ASCII value of “m” is greater than the ASCII value of “M”.
Decisions! Decisions!
Why do you need to know all this? Well, comparison operators come in very useful when building conditional expressions - and conditional expressions come in very useful when adding control routines to your code. Control routines check for the existence of certain conditions, and execute appropriate program code depending on what they find.
The first - and simplest - decision-making routine is the “if” statement, which looks like this:
if (condition)
{
do this!
}
The “condition” here refers to a conditional expression, which evaluates to either true or false. For example,
if (bus is late)
{
con Dad into giving you a ride
}
or, in Perl language
if (bus_arrival == 0)
{
con_Dad();
}
If the conditional expression evaluates as true, all statements within the curly braces are executed. If the conditional expression evaluates as false, all statements within the curly braces will be ignored, and the lines of code following the “if” block will be executed.
Here’s a simple program that illustrates the basics of the “if” statement.
#!/usr/bin/perl
# ask for a number
print ("Gimme a number! ");
$alpha = <STDIN>;
chomp ($alpha);
# ask for a different number
print ("Now gimme a different number! ");
$beta = <STDIN>;
chomp ($beta);
# check
if ($alpha == $beta)
{
print("Can't you read, moron? I need two *different* numbers!\n");
}
print("This is the last line! Go away now!\n");
And they say that the popular conception of programmers as rude, uncouth hooligans is untrue!
In addition to the “if” statement, Perl also allows you a couple of variants - the first is the “if-else” statement, which allows you to execute different blocks of code depending on whether the expression is evaluated as true or false.
The structure of an “if-else” statement looks like this:
if (condition)
{
do this!
}
else
{
do this!
}
In this case, if the conditional expression evaluates as false, all statements within the curly braces of the “else” block will be executed. Modifying the example above, we have
#!/usr/bin/perl
# ask for a number
print ("Gimme a number! ");
$alpha = <STDIN>;
chomp ($alpha);
# ask for a different number
print ("Now gimme a different number! ");
$beta = <STDIN>;
chomp ($beta);
# check
if ($alpha == $beta)
{
print("Can't you read, moron? I need two *different* numbers!\n");
}
else
{
print("Finally! Someone with active brain cells!\n");
}
And here’s another example, this time using strings - the trigger condition here is the input string “yes”.
#!/usr/bin/perl
# ask a question
print ("Did you like Austin Powers 2: The Spy Who Shagged Me?\n");
$response = <STDIN>;
chomp ($response);
# check
if ($response eq "yes")
{
print("Groovy, baby!\n");
}
else
{
print("Loser! May your soul rot in hell!\n");
}
Handling The Gray Areas
Both the “if” and “if-else” constructs are great for black-and-white, true-or-false situations. But what if you need to handle the gray areas as well?
Well, that’s why we have the “if-elsif-else” construct:
if (first condition is true)
{
do this!
}
elsif (second condition is true)
{
do this!
}
elsif (third condition is true)
{
do this!
}
... and so on ...
else
{
do this!
}
You can have as many “elsif” blocks as you like in this kind of construct. The only rule is that the “elsif” blocks must come after the “if” block but before the “else” block.
#!/usr/bin/perl
# movie quote generator
# set up the choices
print("[1] The Godfather\n");
print("[2] American Beauty\n");
print("[3] The Matrix\n");
print("[4] The Usual Suspects\n");
print("[5] Casino\n");
print("[6] Star Wars\n");
print("Gimme a number, and I'll give you a quote!\n");
# get some input
$choice = <STDIN>;
chomp($choice);
# check input and display
if ($choice == 1)
{
print("I'll make him an offer he can't refuse.\n");
}
elsif ($choice == 2)
{
print("It's okay. I wouldn't remember me either.\n");
}
elsif ($choice == 3)
{
print("Unfortunately, no one can be told what the Matrix is. You have to see it for yourself. \n");
}
elsif ($choice == 4)
{
print("The greatest trick the devil ever pulled was convincing the world he didn't exist.\n");
}
elsif ($choice == 5)
{
print("In the casino, the cardinal rule is to keep them playing and to keep them coming back.\n");
}
elsif ($choice == 6)
{
print("I suggest a new strategy, Artoo: let the Wookie win.\n");
}
else
{
print("Invalid choice!\n");
}
Depending on the data you input at the prompt, the “elsif” clauses are scanned for an appropriate match and the correct quote is displayed. In case the number you enter does not correspond with the available choices, the program goes to the “else” routine and displays an error message.
Miscellaneous Notes
Before you go, here are a couple of things that you might find interesting:
chomp() versus chop(): In addition to the chomp() function used above, Perl also has a chop() function. While the chomp() function is used to remove the trailing newline if it exists, the chop() function is designed to remove the last character of a variable, irrespective of whether or not it is a newline character.
#!/usr/bin/perl
# set up the variables
$sacrificial_goat1 = "boom";
$sacrificial_goat2 = "boom";
# chomp it!
chomp($sacrificial_goat1);
print($sacrificial_goat1, "\n");
# chop it!
chop($sacrificial_goat2);
print($sacrificial_goat2, "\n");
Assignment operators versus equality operators: An important point to note - and one which many novice programmers fall foul of - is the difference between the assignment operator [=] and the equality operator [==]. The former is used to assign a value to a variable, while the latter is used to test for equality in a conditional expression.
So
$a = 47;
assigns the value 47 to the variable $a, while
$a == 47
tests whether the value of $a is equal to 47.
Special characters and print(): As you’ve seen, print() can be used in either one of two ways:
#!/usr/bin/perl
$day = "Tuesday";
print("Today is ", $day);
or
#!/usr/bin/perl
$day = "Tuesday";
print "Today is $day";
both of which are equivalent, and return this output:
Today is Tuesday
But now try replacing the double quotes with singles, and watch what happens:
#!/usr/bin/perl
$day = "Tuesday";
print 'Today is $day';
Your output should now read
Today is $day
Thus, single quotes turn off Perl’s “variable interpolation” - simply, the ability to replace variables with their actual value when executing a program. This also applies to special characters like the newline character - single quotes will cause Perl to print the newline character as part of the string, while double quotes will allow it to recognize the character correctly.
You should note this difference in behaviour, if only to save yourself a few minutes of debugging time.
The second thing to note about print() is that you need to “escape” special characters with a backslash. Take a look at this example:
#!/usr/bin/perl
print("She said "Hello" to me, and my heart skipped a beat.");
When you run this, you’ll see a series of error messages - this is because the multiple sets of double quotes within the print() function call confuse Perl. And so, if you’d like your output to contain double quotes [or other special characters], it’s necessary to escape them with a preceding backslash.
#!/usr/bin/perl
print("She said \"Hello\" to me, and my heart skipped a beat.");
As to what happens next - you’ll have to wait for the next lesson in this series, when we’ll be teaching you a few more control structures and introducing you to the different types of loops supported by Perl. See you then!
Note: All examples in this article have been tested on Linux/i586 with Perl 5.005_03. YMMV!
This article was first published on 01 Jun 2000.