Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Perl Web Development - From Novice To Professional (2006)

.pdf
Скачиваний:
56
Добавлен:
17.08.2013
Размер:
2.9 Mб
Скачать

280C H A P T E R 1 3 P E R L W E B S I T E S W I T H M A S O N

<%args> $year </%args>

<p>Copyright (c) <% $year+1900 %>, Steve Suehring</p>

</body>

</html>

Within this code, you’ll notice the addition of the <%args> section. This is because the footer will be called with an argument of the year, which will come from the localtime() function. That localtime() function is now located in the source file, myfirstmason.html, which now looks like this:

<& header.mase &>

% my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

<p>This is all just plain text on my web site. Thanks for visiting today.</p>

<& footer.mase, year => $year &>

Of note in this file is that the header was called into the file with the standard <& . . . &> tags, the Perl localtime() function was called, followed by the HTML for the page, finally followed by the call to the footer file. The call to the footer contained an argument of the year that corresponds to the year in the <%args> section of the footer.mase file. The results from this page are the same as those shown in Figure 13-7.

So that was version 1 of the header and footer example. It’s barely been released when

I want to make improvements to it. For example, it’s really unnecessary to send the year as an argument to the footer. The Perl code for the localtime() function could have just as easily been placed directly in the footer itself. However, using <%args> is something you’ll likely be doing a lot of when developing CGIs with Mason, so I thought it might be helpful to see it again.

Using Return Values

Another improvement I will implement is to place the localtime() function inside its own component with a return value. This final version of the example will use the same three files: filesheader.mase, footer.mase, and myfirstmason.mhtml. A new file will be added called get_year (with no extension). The contents of get_year are shown in Listing 13-7.

Listing 13-7. The get_year Component

<%init>

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); return $year;

</%init>

C H A P T E R 1 3 P E R L W E B S I T E S W I T H M A S O N

281

Even though this function actually returns much more than just the year, the year is all I need for the copyright and is therefore all that’s returned by this function. In practice, I’d likely return the entire date structure as an array.

The contents of footer.mase change to remove the <%args> section and replace it with a call to the component. The contents of footer.mase are now as follows:

% my $year = $m->comp('get_year');

<p>Copyright (c) <% $year+1900 %>, Steve Suehring</p>

</body>

</html>

The previous code could be written without the use of the temporary $year variable:

<p>Copyright (c) <% $m->comp('get_year')+1900 %>, Steve Suehring</p>

</body>

</html>

Finally, the myfirstmason.html file no longer needs to include the year argument in the call to the footer component. The contents are now as follows:

<& header.mase &>

<p>This is all just plain text on my web site. Thanks for visiting today.</p>

<& footer.mase &>

Security Considerations with Mason

Mason doesn’t, by itself, introduce any specific security considerations.

Summary

In this chapter you learned about Mason, a powerful dynamic templating system for Perl. Although Mason can run in a number of environments, the environment covered in this chapter was Apache with mod_perl. You explored the basic building block of Mason, the component, and you learned how to call components. You also covered the various tags available for use with Mason. You examined handlers, specifically dhandlers and autohandlers, and you learned a bit about Mason design.

A P P E N D I X

■ ■ ■

Perl Basics

This appendix contains lightly edited passages from Beginning Perl, Second Edition by James Lee, (Apress, 2004; ISBN: 1-59059-391-X). The goal is to provide you with a refresher course on the basics of Perl. If you’re completely unfamiliar with Perl, I recommend picking up a copy of Beginning Perl to get the most out of this book.

Our First Perl Program

Assuming that you now have a copy of Perl installed on your machine, you are ready to start using Perl. If not, go back and follow the instructions (in Beginning Perl, Second Edition). The next step is to write our first Perl program.

Here’s what it will look like:

#!/usr/bin/perl -w

print "Hello, world!\ n";

We highly suggest that you type this example in and try to make it work, so before we go any further, a quick note on editors. Perl source code is just plain text and should be written with a plain text editor rather than a word processor. Your operating system, whether Unix or Windows, comes with a selection of text editors. You may have a favorite already, so feel free to use it. If not, may we suggest vi (http://www.vim.org), emacs (http://www.xemacs.org), and nedit (http://www.nedit.org). Windows provides WordPad and Notepad, but they lack many features of modern text editors, so they should be avoided. nedit is the most WordPadand Notepad-like, so give it a try.

The next step is to fire up your editor of choice, type in the code shown previously, and save it into a file named helloworld.pl in the directory we just made. Then, to execute it, type

$ perl helloworld.pl

Hello, world!

$

Congratulations! You’ve successfully written and executed your first Perl program.

283

284 A P P E N D I X P E R L B A S I C S

Keywords

A keyword is a term in Perl that has a predefined meaning. One example is the term use as we saw in the statement

use warnings;

Other types of keywords include built-in functions such as print() and control flow constructs such as if and while. We will talk about many built-in functions and control flow constructs in detail as we progress in our discussion of Perl.

It’s a good idea to respect keywords and not give anything else the same name as one. For example, a little later on you’ll learn that you can create and name a variable, and that calling your variable $print is perfectly allowable. The problem with this is that it leads to confusing and uninformative statements like print $print. It is always a good idea to give a variable a meaningful name, one that relates to its content in a logical manner—for example, $my_name,

@telephone_numbers, %account_info, and so on, rather than $a, @b, and %c.

Statements and Statement Blocks

If functions are the verbs of Perl, then statements are the sentences. Instead of a period, a statement in Perl usually ends with a semicolon, as shown earlier:

print "Hello, world!\ n";

To print some more text, we can add another statement:

print "Hello, world!\ n"; print "Goodbye, world!\ n";

Escape Sequences

UTF8 gives us 65,536 characters, and ASCII gives us 256 characters, but on the average keyboard, there’s only a hundred or so keys. Even using the Shift keys, there will still be some characters that you aren’t going to be able to type. There will also be some things that you don’t want to stick in the middle of your program, because they would make it messy or confusing. However, you’ll want to refer to some of these characters in strings that you output. Perl provides us with mechanisms called escape sequences as an alternative way of getting to them. You’ve already seen the use of \ n to start a new line. Table A-1 lists the more common escape sequences.

Table A-1. Escape Sequences

Escape Sequence

Meaning

\ t

Tab

\ n

Start a new line (usually called newline)

\ r

Carriage return

\ b

Back up one character (backspace)

\ a

Alarm (rings the system bell)

\ x{ 1F18}

Unicode character

 

 

A P P E N D I X P E R L B A S I C S

285

In the last example in the table, 1F18 is a hexadecimal number referring to a character in the Unicode character set, which runs from 0000-FFFF. As another example, \ x{ 2620} is the Unicode character for a skull-and-crossbones!

White Space

As mentioned previously, white space is the name we give to tabs, spaces, and newlines. Perl is very flexible about where you put white space in your program. You’ve already seen that you’re free to use indentation to help show the structure of blocks. You don’t need to use any white space at all, if you don’t want to. If you’d prefer, your programs can all look like this:

print"Top level\ n";{ print"2nd level\ n";{ print"3rd level\ n";} print"Where are we?";}

This is considered a bad idea. White space is another tool we have to make our programs more understandable; let’s use it as such.

Types of Data

A lot of programming jargon is about familiar words in an unfamiliar context. You’ve already seen a string, which was a series of characters. You could also describe that string as a scalar literal constant. What does that mean?

By calling a value a scalar, you’re describing the type of data it contains. If you remember your math (and even if you don’t), a scalar is a plain, simple, one-dimensional value. In math, the word is used to distinguish it from a vector, which is expressed as several numbers. Velocity, for example, has a pair of coordinates (speed and direction), and so must be a vector. In Perl, a scalar is the fundamental, basic unit of data of which there are two kinds: numbers and strings.

A literal is value that never changes. The value 5 is a scalar literal—and is literally 5; it can never be 4. Perl has three types of scalar literals: integers (such as 5), floating-point numbers (like 3.14159), and strings (for example, “hello, world”). To put it another way, a literal is a con- stant—it never changes, as opposed to a variable, which is a piece of memory that can hold

a scalar value. Variables are so named because the value stored within them can vary. For instance, $number can be assigned 5, and then later can be changed to the value 6. We will talk more about variables later in this appendix.

Numbers

There are two types of numbers that we’re interested in as Perl programmers: integers and floating-point numbers. The latter we’ll come to in a minute, but let’s work a bit with integers right now. Integers are whole numbers with no numbers after the decimal point, such as 42, –1, or 10. The following program prints a couple of integer literals in Perl:

#!/usr/bin/perl -w

# number1.pl

print 25, -4;

286 A P P E N D I X P E R L B A S I C S

$ perl number1.pl 25-4$

Well, that’s what we see, but it’s not exactly what we want. Fortunately, this is pretty easy to fix. First, we didn’t tell Perl to separate the numbers with a space, and second, we didn’t tell it to put a new line on the end. Let’s change the program so it does that:

#!/usr/bin/perl -w

# number2.pl

print 25, " ", -4, "\ n";

This will do what we were thinking of:

$ perl number2.pl 25 -4

$

For the purpose of human readability, we often write large integers such as 10000000 by splitting up the number with commas: 10,000,000. This is sometimes known as chunking. While we might write 10 million with a comma if we wrote a check for that amount, don’t use the comma to chunk in a Perl program. Instead, use the underscore: 10_000_000. Change the program to look like the following:

#!/usr/bin/perl -w

# number3.pl

print 25_000_000, " ", -4, "\ n";

Notice that those underscores don’t appear in the output:

$ perl number3.pl 25000000 –4

$

As well as integers, there’s another type of number: floating-point numbers. These contain everything else, such as 0.5, –0.01333, and 1.1.

Note that floating-point numbers are accurate to a certain number of digits. For instance, the number 15.39 may in fact be stored in memory as 15.3899999999999. This is accurate enough for most scientists, so it will have to be for us programmers as well.

Here is an example of printing the approximate value of pi:

#!/usr/bin/perl -w

# number4.pl

print "pi is approximately: ", 3.14159, "\ n";

Executing this program produces the following result:

$ perl number4.pl

pi is approximately: 3.14159

$

A P P E N D I X P E R L B A S I C S

287

Binary, Hexadecimal, and Octal Numbers

We can express numbers as binary, hexadecimal, or octal numbers in our programs. Let’s look at a program to demonstrate how we use the various number systems. Type in the following code, and save it as goodnums.pl:

#!/usr/bin/perl -w

# goodnums.pl

print 255,

"\ n";

print 0377,

"\ n";

print

0b11111111, "\

n";

print

0xFF,

"\

n";

All of these are representations of the number 255, and accordingly, we get the following output:

$ perl goodnums.pl 255 255 255 255

$

When Perl reads this program, it reads and understands numbers in any of the allowed number systems: 0 for octal, 0b for binary, and 0x for hex.

What happens, you might ask, if you specify a number in the wrong system? Well, let’s try it out. Edit goodnums.pl to give a new program, badnums.pl, that looks like this:

#!/usr/bin/perl -w

# badnums.pl

print 255,

"\ n";

print 0378,

"\ n";

print

0b11111112, "\

n";

print

0xFG,

"\

n";

Since octal digits only run from 0 to 7, binary digits from 0 to 1, and hex digits from 0 to F, none of the last three lines make any sense. Let’s see what Perl makes of it:

$ perl badnums.pl

Bareword found where operator expected at badnums.pl line 7, near "0xFG" (Missing operator before G?)

Illegal octal digit '8' at badnums.pl line 5, at end of line Illegal binary digit '2' at badnums.pl line 6, at end of line syntax error at badnums.pl line 7, near "0xFG"

Execution of badnums.pl aborted due to compilation errors.

$

Now, let’s match those errors up with the relevant lines:

Illegal octal digit '8' at badnums.pl line 5, at end of line

288 A P P E N D I X P E R L B A S I C S

And line 5 is

print 0378,

"\ n";

As you can see, Perl thought it was dealing with an octal number, but then along came an 8, which stopped making sense, so Perl quite rightly complained. The same thing happened on the next line:

Illegal binary digit '2' at badnums.pl line 6, at end of line

And line 4 is

print 0b11111112, "\ n";

The problem with the next line is even bigger:

Bareword found where operator expected at badnums.pl line 7, near "0xFG" (Missing operator before G?)

syntax error at badnums.pl line 7, near "0xFG"

The line starting “Bareword” is a warning (since we are using the -w option). Then it is followed by a syntax error. A bareword is a series of characters outside of a string that Perl doesn’t recognize. The word could mean a number of things, and Perl is usually quite good about knowing what you mean. In this case, the bareword was G: Perl had understood 0xF, but couldn’t see how the G fit in. We might have wanted an operator do something with it, but there was no operator there. In the end, Perl gave us a syntax error, which is the equivalent of it giving up and saying, “How do you expect me to understand this?”

Strings

The other type of scalar available to us is the string, and you’ve already seen a few examples of them. Earlier in the appendix, you met the string "Hello, world!\ n". A string is a series of characters surrounded by some sort of quotation marks. Strings can contain ASCII (or Unicode) data and escape sequences such as the \ n of our example, and there is no maximum length restriction on a string imposed by Perl. Practically speaking, there is a limit imposed by the amount of memory in your computer, but it’s quite hard to hit.

Singlevs. Double-Quoted Strings

The quotation marks you choose for your string are significant. So far you’ve only seen double-quoted strings, like this: "Hello, world!\ n". There is another type of string—one that has been single-quoted. Predictably, they are surrounded by single quotes: ''. The important difference is that no processing is done within single-quoted strings, except on \ \ and \ '. You’ll also see later that variable names inside double-quoted strings are replaced by their contents, whereas single-quoted strings treat them as ordinary text. You call both these types of processing interpolation, and say that single-quoted strings are not interpolated.

Consider the following program, bearing in mind that \ t is the escape sequence that represents a tab.

#!/usr/bin/perl -w

# quotes.pl

A P P E N D I X P E R L B A S I C S

289

print '\ tThis is a single-quoted string.\ n'; print "\ tThis is a double-quoted string.\ n";

The double-quoted string will have its escape sequences processed, and the singlequoted string will not. The output is

$ perl quotes.pl

 

\

tThis is a single quoted string.\ n

This is a double-quoted string.

$

 

 

What do we do if we want to have a backslash in a string? This is a common concern for Windows users, as a Windows path looks something like this: C:\ WINNT\ Profiles\. . .. In a double-quoted string, a backslash will start an escape sequence, which is not what we want it to do.

There is, of course, more than one way to do it. We can either use a single-quoted string, as shown previously, or we can escape the backslash. One principle that you’ll see often in Perl, and especially when you get to regular expressions, is that you can use a backslash to turn off any special effect a character may have. This operation is called escaping or, more commonly, backwhacking.

In this case, we want to turn off the special effect a backslash has, and so we escape it:

#!/usr/bin/perl -w

# quotes2.pl

print "C:\ \ WINNT\ \ Profiles\ \ \ n"; print 'C:\ WINNT\ Profiles\ ', "\ n";

This prints the following:

$ perl quotes2.pl C:\ WINNT\ Profiles\ C:\ WINNT\ Profiles\

$

Aha! Some of you may have gotten this message instead:

Can't find string terminator " ' " anywhere before EOF at quotes2.pl line 5.

The reason for this is that you probably left out the space character in line 5 before the second single quote. Remember that \ ' tells Perl to escape the single quote, and so it merrily heads off to look for the next quote, which of course is not there. Try this program to see how Perl treats these special cases:

#!/usr/bin/perl -w

# aside1.pl

print 'ex\ \ er\ \ ' , ' ci\ ' se\ '' , "\ n";

The output you get this time is

$ perl aside1.pl ex\ er\ ci' se'