Scalars, strings and the my keyword
Naming a value with my, the arithmetic you expect from numbers, gluing text with a dot, and the two kinds of quotes — one that fills values in and one that does not.
A name for one value
A scalar holds one thing: a number, a piece of text, or nothing at all. You give it a name with my $count = 3;, and every scalar name starts with a dollar sign. The my is not a formality — it declares the name, and strict mode insists on seeing that declaration before the name is used.
There are no types to declare. The same variable can hold 3 and then the word three, and Perl decides what a value means from the operator you use on it. That is convenient here and it is also the source of the most famous trap in the language, which the chapter on decisions comes back to.
Numbers, and one dot to glue text
Arithmetic is the arithmetic you expect, and division is real division: 10 / 4 is 2.5. 2 ** 10 is a power, % gives the remainder, and whole numbers do not wrap around at some fixed size, so large sums simply work.
The dot joins two pieces of text: 'Mr ' . $name. It is not addition, even when both sides look like numbers — "10" . 5 is the text 105 while "10" + 5 is the number 15. Perl reads the operator to decide what each value is, and that pair is the clearest way to see the rule in action.
Two kinds of quotes
In double quotes a variable is replaced by what it holds: "Hello, $name!". That is interpolation, and it is how Perl text is built instead of gluing pieces together with dots. In single quotes nothing is replaced, so '$name' is four characters of text.
A few escapes are worth knowing for double-quoted text: "\n" is a newline, "\t" is a tab, and a backslash before anything else keeps that character itself. A dollar sign that really means money is written "\$", which is the one escape that surprises people typing prices.
What Perl does when it reads a number
A Perl value does not carry a permanent label saying number or text. The operator decides, and the conversion happens at that moment. A numeric operator reads the leading numeric part of its operand: "12 apples" + 1 is 13, and "apples" + 1 is 0, both with a warning that a non-number was used.
A text operator goes the other way and turns its operands into text first. That is why the same pair of values can be equal under == and different under eq, and why use warnings; is worth keeping on: it names the conversion you did not intend.
Building text a piece at a time
A dot joins two pieces of text into a new one, and .= appends to the variable on the left. The x operator repeats text: '-' x 12 is a rule twelve characters long. These are the three tools behind most small reports, and none of them changes anything until you assign the result.
sprintf is the careful builder. It returns a formatted string instead of printing it, so you can store the line, measure it, or join it to others. printf is sprintf plus a print, and choosing between them is a question of whether you want the text back.
A name with nothing in it
A declared scalar with no value holds undef, which is Perl for "nothing here". In text it prints as an empty string, in arithmetic it counts as zero, and defined asks whether a value is there at all. The distinction matters because use warnings; reports an uninitialised value when you use one, not when you declare it, so a gap in the output is often a name you forgot to assign.
Assigning undef deliberately is a way to clear a value, and testing with defined before printing is how a report avoids a gap where a number should be.
Values, quotes and a few functions you get for free
use strict;
use warnings;
my $name = 'Ada';
my $count = 3;
print "Hello, $name!\n";
print 'Single quotes keep $name as text', "\n";
print 'Mr ' . $name . "\n";
# The operator decides number or text.
print "10" + 5, "\n";
print "10" . 5, "\n";
# length, uc and lc are always there.
print length($name), "\n";
print uc($name), ' ', lc('ADA'), "\n";
print '-' x 12, "\n";Text, numbers and the dot
Run it and check every line against what you expected. Then add a line that prints the length of your own name, and one where a single-quoted word sits between two double-quoted ones.
When two pieces of output look identical but behave differently, print their lengths. A number and a piece of text that reads like a number are easy to mix up, and the length is the quickest way to see which one you have.
The dot joins and the plus adds, so "10" . 5 is 105 while "10" + 5 is 15. Single quotes keep a dollar sign as text, and inside double quotes a real dollar sign needs a backslash: "\$5". Finally, "12 apples" + 1 is 13 rather than an error, so a warning about a non-number is information worth reading.
Try these next
- Build a price label with
sprintf, keeping two decimal places, then print it withprint. - Start with an empty string and append three words to it with
.=, printing the length after each step. - Print the same word in single and double quotes with a variable beside it, and explain which dollar sign was filled in.
An address label and a price
Run it, then change the quantity and the unit price. Add a second item line, and keep every price at two decimal places.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does my $total = 0; do?
