📄 ch15.htm
字号:
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, "give me everything in the <TT>@EXPORT</TT>
list."
<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 15LST04.PL-Using the </B><TT><B><FONT FACE="Courier">integer</FONT></B></TT><B>
Pragma<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
print("Floating point math: ", 10 / 3, "\n");
use integer;
print("Integer math: " 10 / 3, "\n");
</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 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 15LST05.PL-Detecting Symbolic RefereNCes
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
my($foo) = "Testing.";
my($ref);
$ref = \$foo;
print("${$ref}\n"); # Using a real refereNCe
$ref = $foo;
print("${$ref}\n"); # Using a symbolic refereNCe
use strict;
print("${$ref}\n");
</PRE>
</BLOCKQUOTE>
<HR>
<P>
When run with the command <TT>perl 15lst05.pl</TT>,
this program displays:
<BLOCKQUOTE>
<PRE>
Testing.
Can't use string ("Testing.") as a SCALAR ref while "strict refs" 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> "RefereNCes."
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 + -