📄 ch02_11.htm
字号:
<html><head><title>Input Operators (Programming Perl)</title><!-- STYLESHEET --><link rel="stylesheet" type="text/css" href="../style/style1.css"><!-- METADATA --><!--Dublin Core Metadata--><meta name="DC.Creator" content=""><meta name="DC.Date" content=""><meta name="DC.Format" content="text/xml" scheme="MIME"><meta name="DC.Generator" content="XSLT stylesheet, xt by James Clark"><meta name="DC.Identifier" content=""><meta name="DC.Language" content="en-US"><meta name="DC.Publisher" content="O'Reilly & Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Input Operators"><meta name="DC.Type" content="Text.Monograph"></head><body><!-- START OF BODY --><!-- TOP BANNER --><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home"><map name="banner-map"><AREA SHAPE="RECT" COORDS="0,0,466,71" HREF="index.htm" ALT="Programming Perl"><AREA SHAPE="RECT" COORDS="467,0,514,18" HREF="jobjects/fsearch.htm" ALT="Search this book"></map><!-- TOP NAV BAR --><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch02_10.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch02_01.htm">Chapter 2: Bits and Pieces</a></td><td align="right" valign="top" width="172"><a href="ch03_01.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h2 class="sect1">2.11. Input Operators</h2><a name="INDEX-733"></a><a name="INDEX-734"></a><a name="INDEX-735"></a><p>There are several input operators we'll discuss here because they parseas terms. Sometimes we call them pseudoliterals because theyact like quoted strings in many ways. (Output operators like <tt class="literal">print</tt>parse as list operators and are discussed in <a href="ch29_01.htm">Chapter 29, "Functions"</a>.)</p><h3 class="sect2">2.11.1. Command Input (Backtick) Operator</h3><a name="INDEX-736"></a><a name="INDEX-737"></a><a name="INDEX-738"></a><p>First of all, we have the command input operator, also known as thebacktick operator, because it looks like this:<blockquote><pre class="programlisting">$info = `finger $user`;</pre></blockquote>A string enclosed by backticks (grave accents, technically) firstundergoes variable interpolation just like a double-quoted string.The result is then interpreted as a command line by the system, andthe output of that command becomes the value of the pseudoliteral.(This is modeled after a similar operator in Unix shells.) In scalarcontext, a single string consisting of all the output is returned. Inlist context, a list of values is returned, one for each line ofoutput. (You can set <tt class="literal">$/</tt> to use a different lineterminator.)</p><p><a name="INDEX-739"></a>The command is executed each time the pseudoliteral is evaluated. The numeric status value ofthe command is saved in <tt class="literal">$?</tt> (see <a href="ch28_01.htm">Chapter 28, "Special Names"</a> for the interpretation of<tt class="literal">$?</tt>, also known as <tt class="literal">$CHILD_ERROR</tt>).Unlike the <em class="emphasis">csh</em> version of this command, notranslation is done on the return data--newlines remain newlines.Unlike in any of the shells, single quotes in Perl do not hidevariable names in the command from interpretation. To pass a<tt class="literal">$</tt> through to the shell you need to hide it with abackslash. The <tt class="literal">$user</tt> in our<em class="emphasis">finger</em> example above is interpolated by Perl, notby the shell. (Because the command undergoes shell processing, see<a href="ch23_01.htm">Chapter 23, "Security"</a>, for security concerns.)</p><p><a name="INDEX-740"></a><a name="INDEX-741"></a><a name="INDEX-742"></a>The generalized form of backticks is <tt class="literal">qx//</tt> (for "quoted execution"),but the operator works exactly the same way as ordinary backticks.You just get to pick your quote characters. As with similar quotingpseudofunctions, if you happen to choose a single quote as yourdelimiter, the command string doesn't undergo double-quoteinterpolation;<blockquote><pre class="programlisting">$perl_info = qx(ps $$); # that's Perl's $$$shell_info = qx'ps $$'; # that's the shell's $$</pre></blockquote></p><a name="ch02-sect-li"></a><h3 class="sect2">2.11.2. Line Input (Angle) Operator</h3><a name="INDEX-743"></a><a name="INDEX-744"></a><a name="INDEX-745"></a><a name="INDEX-746"></a><a name="INDEX-747"></a><a name="INDEX-748"></a><a name="INDEX-749"></a><a name="INDEX-750"></a><p>The most heavily used input operator is the line input operator,also known as the angle operator or the <tt class="literal">readline</tt> function (sincethat's what it calls internally). Evaluating a filehandle in angle brackets(<tt class="literal">STDIN</tt>, for example) yields the next line from theassociated filehandle. (The newline is included, so according to Perl'scriteria for truth, a freshly input line is always true, up untilend-of-file, at which point an undefined value is returned, whichis conveniently false.) Ordinarily, you would assign the input valueto a variable, but there is one situation where an automaticassignment happens. If and only if the line input operator is theonly thing inside the conditional of a <tt class="literal">while</tt> loop, the value isautomatically assigned to the special variable <tt class="literal">$_</tt>. The assignedvalue is then tested to see whether it is defined. (This may seemlike an odd thing to you, but you'll use the construct frequently,so it's worth learning.) Anyway, the following lines are equivalent:<blockquote><pre class="programlisting">while (defined($_ = <STDIN>)) { print $_; } # the longest waywhile ($_ = <STDIN>) { print; } # explicitly to $_while (<STDIN>) { print; } # the short wayfor (;<STDIN>;) { print; } # while loop in disguiseprint $_ while defined($_ = <STDIN>); # long statement modifierprint while $_ = <STDIN>; # explicitly to $_print while <STDIN>; # short statement modifier</pre></blockquote>Remember that this special magic requires a <tt class="literal">while</tt> loop. If you usethe input operator anywhere else, you must assign the result explicitlyif you want to keep the value:<blockquote><pre class="programlisting">while (<FH1> && <FH2>) { ... } # WRONG: discards both inputsif (<STDIN>) { print; } # WRONG: prints old value of $_if ($_ = <STDIN>) { print; } # suboptimal: doesn't test definedif (defined($_ = <STDIN>)) { print; } # best</pre></blockquote>When you're implicitly assigning to <tt class="literal">$_</tt> in a <tt class="literal">$_</tt> loop, thisis the global variable by that name, not one localized to the<tt class="literal">while</tt> loop. You can protect an existing value of <tt class="literal">$_</tt>this way:<blockquote><pre class="programlisting">while (local $_ = <STDIN>) { print; } # use local $_</pre></blockquote>Any previous value is restored when the loop is done. <tt class="literal">$_</tt> is still a global variable, though, so functions called from inside thatloop could still access it, intentionally or otherwise. You canavoid this, too, by declaring a lexical variable: <blockquote><pre class="programlisting">while (my $line = <STDIN>) { print $line; } # now private</pre></blockquote>(Both of these <tt class="literal">while</tt> loops still implicitly testfor whether the result of the assignment is<tt class="literal">defined</tt>, because <tt class="literal">my</tt> and<tt class="literal">local</tt> don't change how assignment is seen by theparser.) The filehandles <tt class="literal">STDIN</tt>,<tt class="literal">STDOUT</tt>, and <tt class="literal">STDERR</tt> arepredefined and pre-opened. Additional filehandles may be created withthe <tt class="literal">open</tt> or <tt class="literal">sysopen</tt> functions.See those functions' documentation in <a href="ch29_01.htm">Chapter 29, "Functions"</a> for details on this.</p><p><a name="INDEX-751"></a>In the <tt class="literal">while</tt> loops above, we were evaluating the line input operatorin a scalar context, so the operator returns each line separately. However, ifyou use the operator in a list context, a list consisting of all remaininginput lines is returned, one line per list element. It's easy to make a<em class="emphasis">large</em> data space this way, so use this feature with care:<blockquote><pre class="programlisting">$one_line = <MYFILE>; # Get first line.@all_lines = <MYFILE>; # Get the rest of the lines.</pre></blockquote>There is no <tt class="literal">while</tt> magic associated with the listform of the input operator, because the condition of a<tt class="literal">while</tt> loop always provides a scalar context (as doesany conditional).</p><p><a name="INDEX-752"></a>Using the null filehandle within the angle operator is special; itemulates the command-line behavior of typical Unix filterprograms such as <em class="emphasis">sed</em> and <em class="emphasis">awk</em>. When you read lines from<tt class="literal"><></tt>, it magically gives you all the lines from all the filesmentioned on the command line. If no files were mentioned, it gives youstandard input instead, so your program is easy to insert into themiddle of a pipeline of processes.</p><p><a name="INDEX-753"></a>Here's how it works: the first time <tt class="literal"><></tt> is evaluated, the<tt class="literal">@ARGV</tt> array is checked, and if it is null, <tt class="literal">$ARGV[0]</tt> is set to"<tt class="literal">-</tt>", which when opened gives you standard input. The <tt class="literal">@ARGV</tt> arrayis then processed as a list of filenames. More explicitly, the loop:<blockquote><pre class="programlisting">while (<>) { ... # code for each line}</pre></blockquote>is equivalent to the following Perl-like pseudocode:<blockquote><pre class="programlisting">@ARGV = ('-') unless @ARGV; # assume STDIN iff emptywhile (@ARGV) { $ARGV = shift @ARGV; # shorten @ARGV each time if (!open(ARGV, $ARGV)) { warn "Can't open $ARGV: $!\n"; next; } while (<ARGV>) { ... # code for each line }}</pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -