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

📄 ch29_02.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 5 页
字号:
variable's value, an operating system error, etc.  Since <tt class="literal">undef</tt> isjust one kind of false value, a simple Boolean test does notdistinguish between <tt class="literal">undef</tt>, numeric zero, the null string, and theone-character string, "<tt class="literal">0</tt>"--all of which are equally false.  The<tt class="literal">defined</tt> function allows you to distinguish between an undefined nullstring and a defined null string when you're using operators that mightreturn a real null string.</p><p>Here is a fragment that tests a scalar value from a hash:<blockquote><pre class="programlisting">print if defined $switch{D};</pre></blockquote>When used on a hash element like this, <tt class="literal">defined</tt> only tells youwhether the value is defined, not whether the key has an entry inthe hash.  It's possible to have a key whose value is undefined;the key itself however still exists.  Use <tt class="literal">exists</tt> to determinewhether the hash key exists.</p><p>In the next example we exploit the convention that some operations return theundefined value when you run out of data:<blockquote><pre class="programlisting">print "$val\n" while defined($val = pop(@ary));</pre></blockquote>And in this one, we do the same thing with the <tt class="literal">getpwent</tt> functionfor retrieving information about the system's users.<blockquote><pre class="programlisting">setpwent();while (defined($name = getpwent())) {    print "&lt;&lt;$name&gt;&gt;\n";}endpwent();</pre></blockquote>The same thing goes for error returns from syscalls that could validly return a false value:<blockquote><pre class="programlisting">die "Can't readlink $sym: $!"    unless defined($value = readlink $sym);</pre></blockquote>You may also use <tt class="literal">defined</tt> to see whether a subroutine has beendefined yet.  This makes it possible to avoid blowing up on nonexistentsubroutines (or subroutines that have been declared but never given adefinition):<blockquote><pre class="programlisting">indir("funcname", @arglist);sub indir {    my $subname = shift;    no strict 'refs';  # so we can use subname indirectly    if (defined &amp;$subname) {        &amp;$subname(@_);    # or $subname-&gt;(@_);    }    else {        warn "Ignoring call to invalid function $subname";    }}</pre></blockquote>Use of <tt class="literal">defined</tt> on aggregates (hashes and arrays) is deprecated.(It used to report whether memory for that aggregate had ever beenallocated.)  Instead, use a simple Boolean test to see whether the array or hash has any elements:<blockquote><pre class="programlisting">if (@an_array) { print "has array elements\n" }if (%a_hash)   { print "has hash members\n"   }</pre></blockquote>See also <tt class="literal">undef</tt> and <tt class="literal">exists</tt>.</p><h3 class="sect2">29.2.24. delete&nbsp;&nbsp;&nbsp;&nbsp;</h3><p><blockquote><pre class="programlisting">delete <em class="replaceable">EXPR</em></pre></blockquote><a name="INDEX-4721"></a><a name="INDEX-4722"></a><a name="INDEX-4723"></a><a name="INDEX-4724"></a><a name="INDEX-4725"></a>This function deletes an element (or a slice of elements) from thespecified hash or array.  (See <tt class="literal">unlink</tt> if you want to delete afile.)  The deleted elements are returned in the order specified,though this behavior is not guaranteed for tied variables such as DBMfiles.  After the delete operation, the <tt class="literal">exists</tt> function will returnfalse on any deleted key or index.  (In contrast, after the <tt class="literal">undef</tt>function, the <tt class="literal">exists</tt> function continues to return true, because the<tt class="literal">undef</tt> function only undefines the value of the element, but doesn'tdelete the element itself.)</p><p>Deleting from the <tt class="literal">%ENV</tt> hash modifies theenvironment.  Deleting from a hash that is bound to a (writable)DBM file deletes the entry from that DBM file.</p><p>Historically, you could only delete from a hash, but with Perl version 5.6you may also delete from an array.  Deleting from an array causes theelement at the specified position to revert to a completelyuninitialized state, but it doesn't close up the gap, since that wouldchange the positions of all the subsequent entries.  Use a <tt class="literal">splice</tt>for that. (However, if you delete the final element in an array, thearray size will shrink by one (or more, depending on the position of thenext largest existing element (if any))).</p><p><em class="replaceable">EXPR</em> can be arbitrarily complicated, provided that the finaloperation is a hash or array lookup:<blockquote><pre class="programlisting"># set up array of array of hash$dungeon[$x][$y] = \%properties;# delete one property from hashdelete $dungeon[$x][$y]{"OCCUPIED"};# delete three properties all at once from hashdelete @{ $dungeon[$x][$y] }{ "OCCUPIED", "DAMP", "LIGHTED" };# delete reference to %properties from arraydelete $dungeon[$x][$y];</pre></blockquote>The following na&amp;#239;ve example inefficiently deletes all the values ofa <tt class="literal">%hash</tt>:<blockquote><pre class="programlisting">foreach $key (keys %hash) {    delete $hash{$key};}</pre></blockquote>And so does this:<blockquote><pre class="programlisting">delete @hash{keys %hash};</pre></blockquote>But both of these are slower than just assigning the empty listor undefining it:<blockquote><pre class="programlisting">%hash = ();         # completely empty %hashundef %hash;        # forget %hash ever existed</pre></blockquote>Likewise for arrays:<blockquote><pre class="programlisting">foreach $index (0 .. $#array) {    delete $array[$index];}</pre></blockquote>and:<blockquote><pre class="programlisting">delete @array[0 .. $#array];</pre></blockquote>are less efficient than either of:<blockquote><pre class="programlisting">@array = ();         # completely empty @arrayundef @array;        # forget @array ever existed</pre></blockquote></p><h3 class="sect2">29.2.25. die&nbsp;&nbsp;&nbsp;&nbsp; <img src="figs/dollarat.gif"></h3><p><blockquote><pre class="programlisting">die <em class="replaceable">LIST</em>die</pre></blockquote><a name="INDEX-4726"></a><a name="INDEX-4727"></a><a name="INDEX-4728"></a>Outside an <tt class="literal">eval</tt>, this function prints the concatenated valueof <em class="replaceable">LIST</em> to <tt class="literal">STDERR</tt> and exits with the current value of <tt class="literal">$!</tt>(the C-library <tt class="literal">errno</tt> variable). If <tt class="literal">$!</tt> is 0, it exits with thevalue of <tt class="literal">$? &gt;&gt; 8</tt> (which is the status of the lastreaped child from a <tt class="literal">system</tt>, <tt class="literal">wait</tt>, <tt class="literal">close</tt> on a pipe, or<tt class="literal">`command`</tt>). If <tt class="literal">$? &gt;&gt; 8</tt> is 0, it exitswith 255.</p><p>Within an <tt class="literal">eval</tt>, the function sets the <tt class="literal">$@</tt> variable to theerror message that would have otherwise been produced, then aborts the<tt class="literal">eval</tt>, which returns <tt class="literal">undef</tt>.  The <tt class="literal">die</tt> functioncan thus be used to raise named exceptions that can be caught at ahigher level in the program.  See <tt class="literal">eval</tt>later in this chapter.</p><p>If <em class="replaceable">LIST</em> is a single object reference, that object is assumed to bean exception object and is returned unmodified as the exception in <tt class="literal">$@</tt>.</p><p>If <em class="replaceable">LIST</em> is empty and <tt class="literal">$@</tt> already contains a string value (typically froma previous <tt class="literal">eval</tt>) that value is reused after appending<tt class="literal">"\t...propagated"</tt>.  This is useful for propagating (reraising) exceptions:<blockquote><pre class="programlisting">eval { ... };die unless $@ =~ /Expected exception/;</pre></blockquote>If <em class="replaceable">LIST</em> is empty and <tt class="literal">$@</tt> already contains an exception object, the<tt class="literal">$@-&gt;PROPAGATE</tt> method is called to determine how the exception shouldbe propagated.</p><p>If <em class="replaceable">LIST</em> is empty and <tt class="literal">$@</tt>is empty, then the string <tt class="literal">"Died"</tt> is used.</p><p>If the final value of <em class="replaceable">LIST</em> does not end ina newline (and you're not passing an exception object), the currentscript filename, line number, and input line number (if any) areappended to the message, as well as a newline.  Hint: sometimesappending <tt class="literal">", stopped"</tt> to your message willcause it to make better sense when the string <tt class="literal">"at scriptnameline 123"</tt> is appended.  Suppose you are running script<em class="emphasis">canasta</em>; consider the difference between thefollowing two ways of dying:<blockquote><pre class="programlisting">die "/usr/games is no good";die "/usr/games is no good, stopped";</pre></blockquote>which produce, respectively:<blockquote><pre class="programlisting">/usr/games is no good at canasta line 123./usr/games is no good, stopped at canasta line 123.</pre></blockquote>If you want your own error messages reporting the filename andline number, use the <tt class="literal">__FILE__</tt> and <tt class="literal">__LINE__</tt> special tokens:<blockquote><pre class="programlisting">die '"', __FILE__, '", line ', __LINE__, ", phooey on you!\n";</pre></blockquote>This produces output like:<blockquote><pre class="programlisting">"canasta", line 38, phooey on you!</pre></blockquote>One other style issue--consider the following equivalent examples:<blockquote><pre class="programlisting">die "Can't cd to spool: $!\n"   unless chdir '/usr/spool/news';chdir '/usr/spool/news'         or die "Can't cd to spool: $!\n"</pre></blockquote>Because the important part is the <tt class="literal">chdir</tt>, thesecond form is generally preferred.</p><p>See also <tt class="literal">exit</tt>, <tt class="literal">warn</tt>, <tt class="literal">%SIG</tt>, and the <tt class="literal">Carp</tt> module.</p><h3 class="sect2">29.2.26. do (block)&nbsp;&nbsp;&nbsp;&nbsp;</h3><p><blockquote><pre class="programlisting">do <em class="replaceable">BLOCK</em></pre></blockquote><a name="INDEX-4729"></a>The <tt class="literal">do</tt><em class="replaceable">BLOCK</em> formexecutes the sequence of statements in the<em class="replaceable">BLOCK</em> and returns the value of the lastexpression evaluated in the block.  When modified by a<tt class="literal">while</tt> or <tt class="literal">until</tt> statementmodifier, Perl executes the <em class="replaceable">BLOCK</em> oncebefore testing the loop condition.  (On other statements the loopmodifiers test the conditional first.) The <tt class="literal">do</tt><em class="replaceable">BLOCK</em> itself does <em class="emphasis">not</em>count as a loop, so the loop control statements<tt class="literal">next</tt>, <tt class="literal">last</tt>, or<tt class="literal">redo</tt> cannot be used to leave or restart theblock. See the section "Bare Blocks" in <a href="ch04_01.htm">Chapter 4, "Statements and Declarations"</a>, for workarounds.</p><h3 class="sect2">29.2.27. do (file)&nbsp;&nbsp;&nbsp;&nbsp; <img src="figs/dollarbang.gif"> <img src="figs/taintgrey.gif"> <img src="figs/xt.gif"></h3><p><blockquote><pre class="programlisting">do <em class="replaceable">FILE</em></pre></blockquote><a name="INDEX-4730"></a><a name="INDEX-4731"></a>The <tt class="literal">do</tt><em class="replaceable">FILE</em> form usesthe value of <em class="replaceable">FILE</em> as a filename andexecutes the contents of the file as a Perl script. Its primary use is(or rather was) to include subroutines from a Perl subroutine library,so that:<blockquote><pre class="programlisting">do 'stat.pl';</pre></blockquote>is rather like:<blockquote><pre class="programlisting">scalar eval `cat stat.pl`;   # `type stat.pl` on Windows</pre></blockquote>except that <tt class="literal">do</tt> is more efficient, more concise,keeps track of the current filename for error messages, searches allthe directories listed in the <tt class="literal">@INC</tt> array, andupdates <tt class="literal">%INC</tt> if the file is found.  (See <a href="ch28_01.htm">Chapter 28, "Special Names"</a>.)  It also differs in that codeevaluated with <tt class="literal">do</tt><em class="replaceable">FILE</em>cannot see lexicals in the enclosing scope, whereas code in<tt class="literal">eval</tt><em class="replaceable">FILE</em> does.  It'sthe same, however, in that it reparses the file every time you callit--so you might not want to do this inside a loop unless the filenameitself changes at each loop iterat

⌨️ 快捷键说明

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