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

📄 ch16.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
how the nesting is done with two <TT><FONT FACE="Courier">#ifdef</FONT></TT>

blocks:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">#ifdef S1<BR>

#ifdef S2<BR>

print (&quot;Both S1 and S2 are defined \n&quot;);<BR>

#else<BR>

print (&quot;S1 yes but not S2\n&quot;);<BR>

#endif<BR>

#else<BR>

#ifdef S2<BR>

print (&quot;S2 yes but not S1\n&quot;);<BR>

#else<BR>

print (&quot;neither S1 nor S2\n&quot;);<BR>

#endif<BR>

#endif</FONT></TT>

</BLOCKQUOTE>

<P>

Normally, you would include other Perl programs and modules with

the <TT><FONT FACE="Courier">require</FONT></TT> and <TT><FONT FACE="Courier">use</FONT></TT>

statements. You can also use the <TT><FONT FACE="Courier">#include</FONT></TT>

directive of the C preprocessor to include the contents of another

file. The syntax for the <TT><FONT FACE="Courier">#include</FONT></TT>

command is

<BLOCKQUOTE>

<TT><FONT FACE="Courier">#include <I>filename</I></FONT></TT>

</BLOCKQUOTE>

<P>

where <TT><I><FONT FACE="Courier">filename</FONT></I></TT> is

the name of the file to be included.

<P>

For example, the following command includes the contents of <TT><FONT FACE="Courier">math.h</FONT></TT>

as part of the program:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">#include &lt;math.h&gt;</FONT></TT>

</BLOCKQUOTE>

<P>

The contents of <TT><FONT FACE="Courier">math.h</FONT></TT> will

also be run through the C preprocessor before it's included. The

C preprocessor searches for the included file in the current directory

and, if not found, in the <BR>

<TT><FONT FACE="Courier">/usr/local/lib/perl</FONT></TT> directory.

You can use the <TT><FONT FACE="Courier">-I</FONT></TT> option

to search in other directories for source and include files. 

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

Input from </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">STDIN</FONT></TT></A>

</H2>

<P>

In a Perl script, you can easily read the standard input for responses

with the <TT><FONT FACE="Courier">&lt;STDIN&gt;</FONT></TT> file

handle. The following three lines of code show you how to get

a number from a user and return the square root of the number:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">print &quot;\nEnter a number:&quot;;

<BR>

$answer = &lt;STDIN&gt;;<BR>

print &quot;Sq. root of $answer = &quot;, sqrt($answer), &quot;\n&quot;;</FONT></TT>

</BLOCKQUOTE>

<P>

This little gem of code works great as long you are careful enough

to enter only positive numbers. Enter a negative number, and the

script bombs. Therefore, before taking the square root, you have

to check to see if the number is greater than or equal to zero;

otherwise, you have to bail out with an error message.

<P>

Another annoying fact is that reading <TT><FONT FACE="Courier">$answer=&lt;STDIN&gt;</FONT></TT>

also brings along the <TT><FONT FACE="Courier">\n</FONT></TT>

end-of-line character. Therefore, to remove this appendage from

<TT><FONT FACE="Courier">$answer</FONT></TT>, you have to call

the function <TT><FONT FACE="Courier">chop($answer)</FONT></TT>.

<P>

<TT><FONT FACE="Courier">The &lt;STDIN&gt;</FONT></TT> operation

is used to read from the <TT><FONT FACE="Courier">STDIN</FONT></TT>

file handle for reading from standard input. To read each line

one at a time from the standard input <TT><FONT FACE="Courier">&lt;STDIN&gt;</FONT></TT>,

you use a program like this one:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">while ($_ = &lt;STDIN&gt;) {<BR>

chop($_);<BR>

print $_;<BR>

}</FONT></TT>

</BLOCKQUOTE>

<P>

Because <TT><FONT FACE="Courier">$_</FONT></TT> is the default

storage area for the last line read in a Perl script, any references

to <TT><FONT FACE="Courier">$_</FONT></TT> can be removed when

implicitly implied. For example, the previous excerpt of code

could be written as this:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">while (&lt;STDIN&gt;) {<BR>

chop;<BR>

print;<BR>

}</FONT></TT>

</BLOCKQUOTE>

<P>

To read complete files by specifying the filename from the command

line, you can use the <TT><FONT FACE="Courier">&lt;&gt;</FONT></TT>

operator. For example, the following code reads and prints the

contents of the files specified on the command line:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">while (&lt;&gt;) {<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print

$_;<BR>

}</FONT></TT>

</BLOCKQUOTE>

<P>

In this way, you are reading all the files specified on the command

line and then processing the contents of the files one line at

time by simply printing the contents of each. Think of this as

an equivalent to saying <TT><FONT FACE="Courier">cat file1 file2

file3 &#133;</FONT></TT> and so on. The <TT><FONT FACE="Courier">&lt;&gt;</FONT></TT>

is equivalent to <TT><FONT FACE="Courier">&lt;ARGV&gt;</FONT></TT>

where <TT><FONT FACE="Courier">ARGV</FONT></TT> is either <TT><FONT FACE="Courier">STDIN</FONT></TT>

if no files were specified or the contents of all the files in

the order they were specified at the command line. 

<H3><A NAME="TheTermQueryModule">The <TT><FONT SIZE=4 FACE="Courier">Term::Query</FONT></TT><FONT SIZE=4>

Module</FONT></A></H3>

<P>

The previous example for getting the square root of a number is

a very simple example of what you normally run into when getting

user responses to questions. Your query expects a response of

<I>Y</I> for Yes and <I>N</I> for No, but the user's response

might be a firm <I>M</I> for Maybe. If you have twenty questions,

the last thing you want to do is to have to verify the responses.

This is when it's nice to have modules that do the work for you.

<P>

<TT><FONT FACE="Courier">Term::Query</FONT></TT> is a Perl 5 module

written by Alan K. Stebbens. The module is used to provide a set

of questions, a default response, a set of expected responses

per question, and a help string to assist the end user. Not all

of these items have to be specified; only the query is required.

<P>

If you do not specify a set of expected return values to a query,

the module will accept anything as input. On the other hand, if

you do specify a set of parameters, the module will validate the

responses for you.

<P>

The default response to a query can also be set. The default response

is displayed between square brackets. If no default is specified,

there will be no such response displayed for the user.

<P>

Finally, you can specify a help string for the input question.

This string is displayed if the user types <B>?</B> at the prompt.

You can disable the display of the help string if you want ? to

be an acceptable response to a query. The help messages can also

be based on expected input types. There are built-in help messages

for some types of input that are displayed even if you do not

explicitly specify a help message. The built-in help strings are

quite verbose and may be enough for most general cases.

<P>

If at any time during the entry and validation process a bizarre

response is given, the module can stop and ask the same question

again. This capability to ask the same query again until a correct

response is received (or the user types the Ctrl+C key combination)

is great for ensuring that the right user responses get into your

Perl script.

<P>

The module itself contains more details about its internal operations.

The documenation is located in the module in the Perl 5 &quot;pod&quot;

format. You can convert a pod file into a man page with the following

command:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">pod2man Query.pm | nroff -man - | less</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">pod2man</FONT></TT> code was developed

in version 5.001m  and requires at least <TT><FONT FACE="Courier">Perl5.001m</FONT></TT>.

This is because the <TT><FONT FACE="Courier">pod2man</FONT></TT>

code uses references in the <TT><FONT FACE="Courier">Carp.pm</FONT></TT>

module to diagnose itself and in the <TT><FONT FACE="Courier">PrintArray.pm</FONT></TT>

module. (Both modules are written by Alan Stebbens.)

<P>

Installing the module is easy. First check to see whether you

have the module already in your distribution. Go to your <TT><FONT FACE="Courier">/usr/lib/perl5,

/usr/local/lib/perl5/site_perl</FONT></TT>, or <TT><FONT FACE="Courier">/usr/local/lib/perl5</FONT></TT>

directory (or wherever you have installed Perl) and look for the

file <TT><FONT FACE="Courier">Query.pm</FONT></TT>. The file will

most likely be in the directory <TT><FONT FACE="Courier">/usr/lib/perl5/Term</FONT></TT>.

<P>

If you cannot find the file, you can get it from the ftp sites

at <TT><FONT FACE="Courier">hubs.ucsb.edu/pub</FONT></TT> and

<TT><FONT FACE="Courier">ikra.com:/pub/perl/modules</FONT></TT>.

Here's a list of the modules you need:

<UL>

<LI><TT><FONT FACE="Courier">Term-Query-1.15.tar.gz</FONT></TT>

for the <TT><FONT FACE="Courier">Term</FONT></TT> module

<LI><TT><FONT FACE="Courier">PrintArray-1.1.tar.gz</FONT></TT>,

a required module for <TT><FONT FACE="Courier">Term</FONT></TT>

</UL>

<P>

Unzip and un<TT><FONT FACE="Courier">tar</FONT></TT> these files

in a place away from the <TT><FONT FACE="Courier">PERLLIBDIR</FONT></TT>

directory.

<P>

You have to set the environment variable <TT><FONT FACE="Courier">PERLLIBDIR</FONT></TT>

to either <TT><FONT FACE="Courier">/usr/lib/perl5</FONT></TT>

or <TT><FONT FACE="Courier">/usr/local/lib/perl5</FONT></TT>.

<P>

Copy the <TT><FONT FACE="Courier">Query.pm</FONT></TT> file into

the <TT><FONT FACE="Courier">$PERLLIBDIR/Term</FONT></TT> directory.

You have to be superuser to do this. Create the directory if you

do not already have it. Copy the <TT><FONT FACE="Courier">PrintArray.pm</FONT></TT>

file into the location <TT><FONT FACE="Courier">PERLLIBDIR</FONT></TT>.

You can use the Makefiles that come with the modules, but the

copying method has proved to work without having to edit any pathnames

in the Makefiles. It's worth taking a look at the test target

in the Makefile to see how the regression tests are done in the

test directory.

<P>

There is one primary subroutine, called <TT><FONT FACE="Courier">query</FONT></TT>,

which is called to process one interaction with the user. The

subroutine <TT><FONT FACE="Courier">query()</FONT></TT> is passed

a prompt and some flags, optionally followed by additional arguments,

depending on the particular flags. Each flag is a single character

and indicates the following values:

<UL>

<LI><FONT COLOR=#000000>The input type: integer, real, string,

yes/no, keyword, or non-keyword</FONT>

<LI><FONT COLOR=#000000>What default input to use in the absence

of user input</FONT>

<LI><FONT COLOR=#000000>An optional help string to be displayed

for errors or input of a question mark (</FONT><TT><FONT FACE="Courier">?</FONT></TT>)

<LI><FONT COLOR=#000000>Any required input validation, such as

regular expression or pattern matching, maximum length, and so

on</FONT>

<LI><FONT COLOR=#000000>Any use of </FONT><TT><FONT FACE="Courier">chop()</FONT></TT>

or white space removal

</UL>

<P>

I'll cover these options with some samples. The following sections

describe how you can use the module.

<H3><A NAME="UsingtheTermQueryModule">Using the <TT><FONT SIZE=4 FACE="Courier">Term::Query</FONT></TT><FONT SIZE=4>

Module</FONT></A></H3>

<P>

Here's the syntax for the call to the <TT><FONT FACE="Courier">query</FONT></TT>

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$result = query($prompt, $flags, [optional

fields]);</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">$prompt</FONT></TT> string is displayed,

and the response entered is interpreted on the value in <TT><FONT FACE="Courier">$flags</FONT></TT>.

The optional fields may be <TT><FONT FACE="Courier">NULL</FONT></TT>

but must be at least as large as required by the flags.

<P>

What are these flags and how did they get interpreted by <TT><FONT FACE="Courier">query()</FONT></TT>?

The flags indicate the type or attribute of the value. Each flag

may have parameters associated with it. The order in which the

flags are listed must be the same order in which the parameters

are listed. Therefore, if you list flags <TT><FONT FACE="Courier">rdh</FONT></TT>,

then you'll have two more strings in the argument list in the

order of a default string and a help message string.

<P>

There are several flags you can use with the <TT><FONT FACE="Courier">Query</FONT></TT>

package. Some of these you have already seen, some are described

in Table 16.2. There is more documentation on other esoteric flags

included in the module.<BR>

<P>

<CENTER><B>Table 16.2. Flags for the interpretation of input variables.</B></CENTER>

<CENTER>

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

<TR VALIGN=TOP><TD WIDTH=50><CENTER><I>Flag</I></CENTER></TD><TD WIDTH=540><I>Interpretation</I>

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=50><CENTER><TT><FONT FACE="Courier">d</FONT></TT></CENTER>

</TD><TD WIDTH=540>The default response to use if you get no input from the question.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=50><CENTER><TT><FONT FACE="Courier">H</FONT></TT></CENTER>

</TD><TD WIDTH=540>Ignores the question mark as a request for help. Treats it as a response to a question.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=50><CENTER><TT><FONT FACE="Cour

⌨️ 快捷键说明

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