Scalars and Operators

In this second part of a five-part series on scalars in Perl, you’ll learn about operators (both arithmetic and bitwise), among other things. This article is excerpted from chapter two of the book Beginning Perl, written by James Lee (Apress; ISBN: 159059391X).

Alternative Delimiters

That’s all very well, of course, until we want a / in the string. Suppose we want to replace “Slashdot” with “/.”—now we’re back where we started, having to escape things again. Thankfully, Perl allows us to choose our own delimiters so we don’t have to stick with // . Any nonalphanumeric (that is, nonalphabetic and nonnumeric) character can be used as a delimiter, provided it’s the same on both sides of the text. Furthermore, you can use {} , [] , () , and <> as left and right delimiters. Here’s a few ways of doing the print qq/…/; , all of which have the same effect:

#!/usr/bin/perl -w
# quotes6.pl

print qq|’"Hi," said Jack. "Have you read /. today?"’n|;
print qq#’"Hi," said Jack. "Have you read /. today?"’n#;
print qq(‘"Hi," said Jack. "Have you read /. today?"’n);
print qq<‘"Hi," said Jack. "Have you read /. today?"’n>;

We’ll see more of these alternative delimiters when we start working with regular expressions.

Here-Documents

There’s one final way of specifying a string—by means of a here-document. This idea was taken from the Unix shell, and works on any platform. Effectively, it means that you can write a large amount of text within your program, and it will be treated as a string provided it is identified correctly. Here’s an example:

#!/usr/bin/perl -w
# heredoc.pl

print <<EOF;

This is a here-document. It starts on the line after the two arrows,
and it ends when the text following the arrows is found at the beginning
of a line, like this:

EOF

A here-document must start with << and then a label. The label can be anything, but is traditionally EOF (end of file) or EOT (end of text). The label must immediately follow the arrows with no spaces between, unless the same number of spaces precedes the end marker. It ends when the label is found at the beginning of a line. In our case, the semicolon does not form part of the label, because it marks the end of the print() function call.

By default, a here-document works like a double-quoted string. In order for it to work like a single-quoted string, surround the label in single quotes. This will become important when variable interpolation comes into play, as we’ll see later on.

{mospagebreak title=Converting Between Numbers and Strings}

Perl treats numbers and strings on an equal footing, and where necessary, Perl converts between strings, integers, and floating point numbers behind the scenes. There is a special term for this: automatic conversion of scalars. This means that you don’t have to worry about making the conversions yourself, like you do in other languages. If you have a string literal "0.25", and multiply it by four, Perl treats it as a number and gives you the expected answer, 1 . For example:

#!/usr/bin/perl -w
# autoconvert.pl

print "0.25" * 4, "n";

The asterisk ( * ) is the multiplication operator. All of Perl’s operators, including this one, will be discussed in the next section.

There is, however, one area where this automatic conversion does not take place. Octal, hex, and binary numbers in string literals or strings stored in variables don’t get converted automatically.

#!/usr/bin/perl -w
# octhex1.pl

print "0x30n";
print "030n";

gives you

$ perl octhex1.pl
0x30
030
$

If you ever find yourself with a string containing a hex or octal value that you need to convert into a number, you can use the hex() or oct() functions accordingly:

#!/usr/bin/perl -w
# octhex2.pl

print hex("0x30"), "n";
print oct("030"), "n";

This will now produce the expected answers, 48 and 24. Note that for hex() or oct() , the prefix 0x or 0 respectively is not required. If you know that what you have is definitely supposed to be a hex or octal number, then hex(30) and oct(30) will produce the preceding results. As you can see from that, the string "30" and the number 30 are treated as the same.

Furthermore, these functions will stop reading when they get to a digit that doesn’t make sense in that number system:

#!/usr/bin/perl -w
# octhex3.pl

print hex("FFG"), "n";
print oct("178"), "n";

These will stop at FF and 17 respectively, and convert to 255 and 15. Perl will warn you, though, since those are illegal characters in hex and octal numbers.

What about binary numbers? Well, there’s no corresponding bin() function but there is actually a little trick here. If you have the correct prefix in place for any of the number systems ( 0 , 0b , or 0x ), you can use oct() to convert it to decimal. For example,
print oct("0b11010") prints 26.

{mospagebreak title=Operators}

Now we know how to specify our strings and numbers, let’s see what we can do with them. The majority of the things we’ll be looking at here are numeric operators (operators that act on and produce numbers) like plus and minus, which take two numbers as arguments, called operands, and add or subtract them. There aren’t as many string operators, but there are a lot of string functions. Perl doesn’t draw a very strong distinction between functions and operators, but the main difference between the two is that operators tend to go in the middle of their arguments—for example: 2 + 2. Functions go before their arguments and have them separated by commas.

Both of them take arguments, do something with them, and produce a new value; we generally say they return a value, or evaluate to a value. Let’s take a look.

Numeric Operators

The numeric operators take at least one number as an argument, and evaluate to another number. Of course, because Perl automatically converts between strings and numbers, the arguments may appear as string literals or come from strings in variables. We’ll group these operators into three types: arithmetic operators, bitwise operators, and logic operators.

Arithmetic Operators

The arithmetic operators are those that deal with basic mathematics like adding, subtracting, multiplying, dividing, and so on. To add two numbers together, we would write something like this:

#!/usr/bin/perl -w
# arithop1.pl

print 69 + 118, "n";

And, of course, we would see the answer 187. Subtracting numbers is easy too, and we can subtract at the same time:

#!/usr/bin/perl -w
# arithop2.pl

print "21 from 25 is: ", 25 – 21, "n"; print "4 + 13 – 7 is: ", 4 + 13 – 7, "n";

$ perl arithop2.pl
21 from 25 is: 4
4 + 13 – 7 is: 10
$

Our next set of operators (multiplying and dividing) is where it gets interesting. We use the * and / operators to multiply and divide respectively.

#!/usr/bin/perl -w
# arithop3.pl

print "7 times 15 is ", 7 * 15, "n";
print "249 divided by 3 is ", 249 / 3, "n";

The fun comes when you want to multiply something and then add something, or add then divide. Here’s an example of the problem:

#!/usr/bin/perl -w
# arithop4.pl

print 3 + 7 * 15, "n";

This could mean one of two things: either Perl must add the 3 and the 7, and then multiply by 15, or multiply 7 and 15 first, and then add. Which does Perl do? Try it and see . . .

Perl should have given you 108, meaning it did the multiplication first. The order in which Perl performs operations is called operator precedence. Multiply and divide have a higher precedence than add and subtract, and so they get performed first. We can start to draw up a list of precedence as follows:

*/

+-

To force Perl to perform an operation of lower precedence first, we need to use parentheses, like so:

#!/usr/bin/perl -w
# arithop5.pl

print (3 + 7) * 15, "n";

Unfortunately, if you run that, you’ll get a warning and 10 is printed. What happened? The problem is that print() is a function and the parentheses around 3 + 7 are treated as the only argument to print() .

print() as an operator takes a list of arguments, performs an operation (printing them to the screen), and returns a 1 if it succeeds, or no value if it does not. Perl calculated 3 plus 7, printed the result, and then multiplied the result of the returned value (1) by 15, throwing away the final result of 15.

To get what we actually want, then, we need another set of parentheses:

#!/usr/bin/perl -w
# arithop6.pl

print((3 + 7) * 15, "n");

This now gives us the correct answer, 150, and we can put another entry in our list of precedence:

List operators

*/

+-

Next we have the exponentiation operator, ** , which simply raises one number to the power of another—squaring, cubing, and so on. Here’s an example of some exponentiation:

#!/usr/bin/perl -w
# arithop7.pl

print 2**4, " ", 3**5, " ", -2**4, "n";

That’s 2*2*2*2, 3*3*3*3*3, and –2*–2*–2*–2. Or is it?

The output we get is

$ perl arithop7.pl
16 243 -16
$

Hmm, the first two look OK, but the last one’s a bit wrong. –2 to the 4th power should be positive. Again, it’s a precedence issue. Turning a number into a negative number requires an operator, the unary minus operator. It’s called unary because unlike the ordinary minus oper ator, it only takes one argument. Although unary minus has a higher precedence than multiply and divide, it has a lower precedence than exponentiation. What’s actually happening, then, is -(2**4) instead of
(-2)**4 . Let’s put these two operators in our list of precedence as well:

  List operators

 **

  Unary minus

 */

 +-

The last arithmetic operator is % , the remainder, or modulo operator. This calculates the remainder when one number divides another. For example, 6 divides into 15 twice, with a remainder of 3, as our next program will confirm:

#!/usr/bin/perl -w
# arithop8.pl

print "15 divided by 6 is exactly ", 15 / 6, "n";
print "That’s a remainder of ", 15 % 6, "n";

$ perl arithop8.pl
15 divided by 6 is exactly 2.5
That’s a remainder of 3
$

The modulo operator has the same precedence as multiply and divide.

{mospagebreak title=Bitwise Operators}

Up to this point, the operators worked on numbers in the way we think of them. However, as we already know, computers don’t see numbers the same as we do; they see them as a string of bits. These next few operators perform operations on numbers one bit at a time—that’s why we call them bitwise operators. These aren’t used quite so much in Perl as in other languages, but we’ll see them when dealing with things like low-level file access.

First, let’s have a look at the kind of numbers we’re going to use in this section, just so we get used to them:

  1. 0 in binary is 0, but let’s write it as 8 bits: 00000000.
  2. 51 in binary is 00110011. 
     
  3. 85 in binary is 01010101. 
     
  4. 170 in binary is 10101010. 
     
  5. 204 in binary is 11001100. 
     
  6. 255 in binary is 11111111.

Does it surprise you that 10101010 (170) is twice as much as 01010101 (85)? It shouldn’t, when we multiply a number by 10 in base 10, all we do is slap a 0 on the end, so 21 becomes 210. Similarly, to multiply a number by 2 in base 2, we do exactly the same.

People think of bitwise operators as working from right to left; the rightmost bit is called the least significant bit and the leftmost is called the most significant bit.

The AND Operator

The easiest bitwise operator to fathom is called the and operator, and is written &. This compares pairs of bits as follows:

  1. 1 and 1 gives 1.
  2. 1 and 0 gives 0. 
     
  3. 0 and 1 gives 0. 
  4. 0 and 0 gives 0.

For example, 51 & 85 looks like this:

51   00110011
85   01010101
————–
17   00010001

Sure enough, if we ask Perl the following:

#!/usr/bin/perl -w
# bitop1.pl

print "51 ANDed with 85 gives us ", 51 & 85, "n";

it’ll tell us the answer is 17. Notice that since we’re comparing one pair of bits at a time, it doesn’t really matter which way around the arguments go, 51 & 85 is exactly the same as 85 & 51 . Oper ators with this property are called associative operators. Addition (+) and multiplication (*) are also associative: 5 * 12 produces the same result as 12 * 5. Subtraction (–) and division (/) are not associative: 5 – 12 does not produce the same result as 12 – 5.

Here’s another example—look at the bits, and see what you get:

51    00110011
170   10101010
—————
34    00100010

The OR Operator

As well as checking whether the first and the second bits are 1, we can check whether one or another is 1, the or operator in Perl is |. This is how we would calculate 204 | 85 :

204  11001100
85   01010101
————-
221  11011101

Now we produce 0s only if both the bits are 0; if either or both are 1, we produce a 1. As a quick rule of thumb, X & Y will always be smaller or equal to the smallest value of X and Y , and X | Y will be bigger than or equal to the largest value of X or Y .

The XOR Operator

What if you really want to know if one or the other, but not both, are one? For this, you need the exclusive or operator, written as the ^ operator:

204  11001100
170  10101010
————-
102  01100110

Please check back next week for the third part of this article.

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort