⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch15.htm

📁 prrl 5 programs codes in the book
💻 HTM
📖 第 1 页 / 共 4 页
字号:

dispSymbols(\%Foo::);



package Foo;

    $bar = 2;



    sub baz {

        $bar++;

    }

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

bar       | *Foo::bar

baz       | *Foo::baz

</PRE>

</BLOCKQUOTE>

<P>

This example shows that there are only two things in the <TT>%Foo::</TT>

symbol table-only those things that the script placed there. This

is not the case with the <TT>%main::</TT>

symbol table. When I display the entries in <TT>%main::,</TT>

I see over 85 items. Part of the reason for the large number of

names in the <TT>main</TT> package

is that some variables are forced there. For example, <TT>STDIN</TT>,

<TT>STDOUT</TT>, <TT>STDERR</TT>,

<TT>@ARGV</TT>, <TT>@ARGVOUT</TT>,

<TT>%ENV</TT>, <TT>@INC</TT>,

and <TT>%SIG</TT> are forced into

the <TT>main</TT> namespace regardless

of when they are used.

<H2><A NAME="TheTTFONTSIZEFACECourierrequireFONTTTFONTSIZECompilerDirectiveFONT"><FONT SIZE=5 COLOR=#FF0000>

The <TT>require</TT>

Compiler Directive</FONT></FONT></A></H2>

<P>

The <TT>require</TT> directive is

used to load Perl libraries. If you needed to load a library called

<TT>Room.pl</TT>, you would do so

like this:

<BLOCKQUOTE>

<PRE>

require Room.pl;

</PRE>

</BLOCKQUOTE>

<P>

No exporting of symbols is done by the <TT>require</TT>

directive. So all symbols in the libraries must be explicitly

placed into the <TT>main</TT> namespace.

For example, you might see a library that looks like this:

<BLOCKQUOTE>

<PRE>

package abbrev;



sub main'abbrev {

    # code for the fuNCtion

}

</PRE>

</BLOCKQUOTE>

<P>

Two things in this code snippet point out that it is Perl 4 code.

The first is that the package name is in all lowercase. And the

second is that a single quote is used instead of double colons

to indicate a qualifying package name. Even though the <TT>abbrev()</TT>

fuNCtion is defined inside the <TT>abbrev</TT>

package, it is not part of the <TT>%abbrev::</TT>

namespace because of the <TT>main'</TT>

in front of the fuNCtion name.

<P>

The <TT>require</TT> directive can

also indicate that your script needs a certain version of Perl

to run. For example, if you are using refereNCes, you should place

the following statement at the top of your script:

<BLOCKQUOTE>

<PRE>

require 5.000;

</PRE>

</BLOCKQUOTE>

<P>

And if you are using a feature that is available only with Perl

5.002-like prototypes-use the following:

<BLOCKQUOTE>

<PRE>

require 5.002;

</PRE>

</BLOCKQUOTE>

<P>

Perl 4 will generate a fatal error if these lines are seen.<BR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Note</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

Prototypes are not covered in this book. If you are using Perl 5.002 or later, prototypes should be discussed in the documentation that comes with the Perl distribution.</BLOCKQUOTE>



</TD></TR>

</TABLE>

</CENTER>

<P>

<H2><A NAME="TheTTFONTSIZEFACECourieruseFONTTTFONTSIZECompilerDirectiveFONT"><FONT SIZE=5 COLOR=#FF0000>

The <TT>use</TT>

Compiler Directive</FONT></FONT></A></H2>

<P>

When it came time to add modules to Perl, thought was given to

how this could be done and still support the old libraries. It

was decided that a new directive was needed. Thus, <TT>use</TT>

was born.

<P>

The <TT>use</TT> directive will automatically

export fuNCtion and variable names to the <TT>main</TT>

namespace by calling the module's <TT>import()</TT>

fuNCtion. Most modules don't have their own <TT>import()</TT>

fuNCtion; instead they inherit it from the <TT>Exporter</TT>

module. You have to keep in mind that the <TT>import()</TT>

fuNCtion is not applicable to object-oriented modules. Object-oriented

modules should not export any of their fuNCtions or variables.

<P>

You can use the following lines as a template for creating your

own modules:

<BLOCKQUOTE>

<PRE>

package Module;

    require(Exporter);

    @ISA = qw(Exporter);

    @EXPORT = qw(fuNCOne $varOne @variable %variable);

    @EXPORT_OK = qw(fuNCTwo $varTwo);

</PRE>

</BLOCKQUOTE>

<P>

The names in the <TT>@EXPORT</TT>

array will always be moved into the <TT>main</TT>

namespace. Those names in the <TT>@EXPORT_OK</TT>

will be moved only if you request them. This small module can

be loading into your script using this statement:

<BLOCKQUOTE>

<PRE>

use Module;

</PRE>

</BLOCKQUOTE>

<P>

SiNCe <TT>use</TT> is a compiler directive,

the module is loaded as soon as the compiler sees the directive.

This means that the variables and fuNCtions from the module are

available to the rest of your script.

<P>

If you need to access some of the names in the <TT>@EXPORT_OK</TT>

array, use a statement like this:

<BLOCKQUOTE>

<PRE>

use Module qw(:DEFAULT fuNCTwo);     # $varTwo is not exported.

</PRE>

</BLOCKQUOTE>

<P>

ONCe you add optional elements to the <TT>use</TT>

directive you need to explicitly list all of the names that you

want to use. The <TT>:DEFAULT</TT>

is a short way of saying, &quot;give me everything in the <TT>@EXPORT</TT>

list.&quot;

<H2><A NAME="WhatsaPragma"><FONT SIZE=5 COLOR=#FF0000>

What's a Pragma?</FONT></A></H2>

<P>

In a-hopefully futile-effort to confuse programmers, the <TT>use</TT>

directive, was given a second job to do. It turns other compiler

directives on and off. For example, you might want to force Perl

to use integer math instead of floating-point match to speed up

certain sections of your program.

<P>

Remember all of the new terminology that was developed for objects?

The computer scientists have also developed their own term for

a compiler directive. And that term is <I>Pragma</I>. The <TT>use</TT>

statement controls the other pragmas. Listing 15.4 shows a program

that use the <TT>integer</TT> pragma.

<HR>

<BLOCKQUOTE>

<B>Listing 15.4&nbsp;&nbsp;15LST04.PL-Using the </B><TT><B><FONT FACE="Courier">integer</FONT></B></TT><B>

Pragma<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

print(&quot;Floating point math: &quot;, 10 / 3, &quot;\n&quot;);

use integer;

print(&quot;Integer math:        &quot; 10 / 3, &quot;\n&quot;);

</PRE>

</BLOCKQUOTE>

<HR>

<P>

This program displays:

<BLOCKQUOTE>

<PRE>

Floating point math: 3.33333333333333

Integer math:        3

</PRE>

</BLOCKQUOTE>

<P>

Pragmas can be turned off using the <TT>no</TT>

compiler directive. For example, the following statement turns

off the <TT>integer</TT> pragma:

<BLOCKQUOTE>

<PRE>

no integer;

</PRE>

</BLOCKQUOTE>

<P>

Table 15.1 shows a list of the pragmas that you can use.<BR>

<P>

<CENTER><B>Table 15.1&nbsp;&nbsp;Perl's Pragmas</B></CENTER>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD WIDTH=85><CENTER><I>Pragma</I></CENTER></TD><TD WIDTH=505><I>Description</I>

</TD></TR>

<TR><TD WIDTH=85><CENTER>integer</CENTER></TD><TD WIDTH=505>Forces integer math instead of floating point or double precision math.

</TD></TR>

<TR><TD WIDTH=85><CENTER>less</CENTER></TD><TD WIDTH=505>Requests less of something-like memory or cpu time-from the compiler. This pragma has not been implemented yet.

</TD></TR>

<TR><TD WIDTH=85><CENTER>sigtrap</CENTER></TD><TD WIDTH=505>Enables stack backtracing on unexpected signals.

</TD></TR>

<TR><TD WIDTH=85><CENTER>strict</CENTER></TD><TD WIDTH=505>Restricts unsafe constructs. This pragma is highly recommended! Every program should use it.

</TD></TR>

<TR><TD WIDTH=85><CENTER>subs</CENTER></TD><TD WIDTH=505>Lets you predeclare fuNCtion names.

</TD></TR>

</TABLE>

</CENTER>

<P>

<H2><A NAME="TheTTFONTSIZEFACECourierstrictFONTTTFONTSIZEPragmaFONT"><FONT SIZE=5 COLOR=#FF0000>

The <TT>strict</TT>

Pragma</FONT></FONT></A></H2>

<P>

The most important pragma is <TT>strict</TT>.

This pragma generates compiler errors if unsafe programming is

detected. There are three specific things that are detected:

<UL>

<LI>Symbolic refereNCes

<LI>Non-local variables (those not declared with <TT>my()</TT>)

and variables that aren't fully qualified.

<LI>Non-quoted words that aren't subroutine names or file handles.

</UL>

<P>

<I>Symbolic</I> refereNCes use the name of a variable as the refereNCe

to the variable. They are a kind of shorthand widely used in the

C programming language, but not available in Perl. Listing 15.5

shows a program that uses symbolic refereNCes.

<P>



<IMG SRC="pseudo.gif" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/pseudo.gif" BORDER=1 ALIGN=RIGHT><p>

<BLOCKQUOTE>

<I>Declare two variables.<BR>

Initialize </I><TT><I>$ref</I></TT><I>

with a refereNCe to </I><TT><I>$foo</I></TT><I>.

<BR>

DerefereNCe </I><TT><I>$ref</I></TT><I>

and display the result.<BR>

Initialize </I><TT><I>$ref</I></TT><I>

to </I><TT><I>$foo</I></TT><I>.<BR>

DerefereNCe </I><TT><I>$ref</I></TT><I>

and display the result.<BR>

Invoke the strict pragma.<BR>

DerefereNCe </I><TT><I>$ref</I></TT><I>

and display the result.</I>

</BLOCKQUOTE>

<HR>

<BLOCKQUOTE>

<B>Listing 15.5&nbsp;&nbsp;15LST05.PL-Detecting Symbolic RefereNCes

<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<PRE>

my($foo) = &quot;Testing.&quot;;

my($ref);



$ref = \$foo;

print(&quot;${$ref}\n&quot;);     # Using a real refereNCe



$ref = $foo;

print(&quot;${$ref}\n&quot;);     # Using a symbolic refereNCe



use strict;

print(&quot;${$ref}\n&quot;);

</PRE>

</BLOCKQUOTE>

<HR>

<P>

When run with the command <TT>perl 15lst05.pl</TT>,

this program displays:

<BLOCKQUOTE>

<PRE>

Testing.



Can't use string (&quot;Testing.&quot;) as a SCALAR ref while &quot;strict refs&quot; in 

    use at 15lst05.pl line 14.

</PRE>

</BLOCKQUOTE>

<P>

The second print statement, even though obviously wrong, does

not generate any errors. Imagine if you were using a complicated

data structure such as the ones described in <A HREF="ch8.htm" tppabs="http://cheminf.nankai.edu.cn/~eb~/Perl%205%20By%20Example/ch8.htm" >Chapter 8</A> &quot;RefereNCes.&quot;

You could spend hours looking for a bug like this. After the <TT>strict</TT>

pragma is turned on, however, a runtime error is generated when

the same print statement is repeated. Perl even displays the value

of the scalar that attempted to masquerade as the refereNCe value.

<P>

The <TT>strict</TT> pragma ensures

that all variables that are used are either local to the current

block or they are fully qualified. Fully qualifying a variable

name simply means to add the package name where the variable was

defined to the variable name. For example, you would specify the

<TT>$numTables</TT> variable in package

<TT>Room</TT> by saying <TT>$Room::numTables</TT>.

If you are not sure which package a variable is defined in, try

using the <TT>dispSymbols()</TT> fuNCtion

from Listing 15.3. Call the <TT>dispSymbols()</TT>

fuNCtion oNCe for each package that your script uses. 

<P>

The last type of error that <TT>strict</TT>

will generate an error for is the non-quoted word that is not

used as a subroutine name or file handle. For example, the following

line is good:

<BLOCKQUOTE>

<PRE>

$SIG{'PIPE'} = 'Plumber';

</PRE>

</BLOCKQUOTE>

<P>

And this line is bad:

<BLOCKQUOTE>

<PRE>

$SIG{PIPE} = 'Plumber';

</PRE>

</BLOCKQUOTE>

<P>

Perl 5, without the <TT>strict</TT>

pragma, will do the correct thing in the bad situation and assume

that you meant to create a string literal. However, this is considered

bad programming practice.<BR>

<p>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR><TD><B>Tip</B></TD></TR>

<TR><TD>

<BLOCKQUOTE>

Always use the <TT>strict</TT> pragma in your scripts. It will take a little longer to declare everything, but the time saved in debugging will more than make up for it.

</BLOCKQUOTE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -