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

📄 ch06_04.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html><head><title>Prototypes (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 &amp; Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Prototypes"><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="ch06_03.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch06_01.htm">Chapter 6: Subroutines</a></td><td align="right" valign="top" width="172"><a href="ch06_05.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">6.4. Prototypes</h2><a name="INDEX-1847"></a><a name="INDEX-1848"></a><a name="INDEX-1849"></a><p>Perl lets you define your own functions to be called like Perl'sbuilt-in functions.  Consider <tt class="literal">push(@array, $item)</tt>, which musttacitly receive a reference to <tt class="literal">@array</tt>, not just the list valuesheld in <tt class="literal">@array</tt>, so that the array can bemodified.  <em class="emphasis">Prototypes</em> letyou declare subroutines to take arguments just like many of thebuilt-ins, that is, with certain constraints on the number and typesof arguments.  We call them "prototypes", but they work more likeautomatic templates for the calling context than like what C or Javaprogrammers would think of as prototypes.  With these templates, Perlwill automatically add implicit backslashes, or calls to <tt class="literal">scalar</tt>, orwhatever else it takes to get things to show up in a way that matchesthe template.  For instance, if you declare:<blockquote><pre class="programlisting">sub mypush (\@@);</pre></blockquote>then <tt class="literal">mypush</tt> takes arguments exactly like<tt class="literal">push</tt> does.  For this to work, the declaration ofthe function to be called must be visible at compile time. Theprototype only affects the interpretation of function calls when the<tt class="literal">&amp;</tt> character is omitted.  In other words, if youcall it like a built-in function, it behaves like a built-in function.If you call it like an old-fashioned subroutine, then it behaves likean old-fashioned subroutine.  The <tt class="literal">&amp;</tt> suppressesprototype checks and associated contextual effects.<a name="INDEX-1850"></a><a name="INDEX-1851"></a></p><p>Since prototypes are taken into consideration only at compile time,it naturally falls out that they have no influence on subroutinereferences like <tt class="literal">\&amp;foo</tt> or on indirect subroutine calls like<tt class="literal">&amp;{$subref}</tt> or <tt class="literal">$subref-&gt;()</tt>.  Method calls are not influencedby prototypes, either.  That's because the actual function to becalled is indeterminate at compile time, depending as it does oninheritance, which is dynamically determined in Perl.</p><p><a name="INDEX-1852"></a><a name="INDEX-1853"></a>Since the intent is primarily to let you define subroutines thatwork like built-in functions, here are some prototypes you might useto emulate the corresponding built-ins:</p><a name="perl3-chnn-tab-0"></a><table border="1"><tr><th>Declared as</th><th>Called as</th></tr><tr><td><tt class="literal">sub mylink ($$)</tt></td><td><tt class="literal">mylink $old, $new</tt></td></tr><tr><td><tt class="literal">sub myreverse (@)</tt></td><td><tt class="literal">myreverse $a,$b,$c</tt></td></tr><tr><td><tt class="literal">sub myjoin ($@)</tt></td><td><tt class="literal">myjoin ":",$a,$b,$c</tt></td></tr><tr><td><tt class="literal">sub mypop (\@)</tt></td><td><tt class="literal">mypop @array</tt></td></tr><tr><td><tt class="literal">sub mysplice (\@$$@)</tt></td><td><tt class="literal">mysplice @array,@array,0,@pushme</tt></td></tr><tr><td><tt class="literal">sub mykeys (\%)</tt></td><td><tt class="literal">mykeys %{$hashref}</tt></td></tr><tr><td><tt class="literal">sub mypipe (**)</tt></td><td><tt class="literal">mypipe READHANDLE, WRITEHANDLE</tt></td></tr><tr><td><tt class="literal">sub myindex ($$;$)</tt></td><td><tt class="literal">myindex &amp;getstring, "substr"</tt></td></tr><tr><td></td><td><tt class="literal">myindex &amp;getstring, "substr", $start</tt></td></tr><tr><td><tt class="literal">sub mysyswrite (*$;$$)</tt></td><td><tt class="literal">mysyswrite OUTF, $buf</tt></td></tr><tr><td></td><td><tt class="literal">mysyswrite OUTF, $buf, length($buf)-$off, $off</tt></td></tr><tr><td><tt class="literal">sub myopen (*;$@)</tt></td><td><tt class="literal">myopen HANDLE</tt></td></tr><tr><td></td><td><tt class="literal">myopen HANDLE, $name</tt></td></tr><tr><td></td><td><tt class="literal">myopen HANDLE, "-|", @cmd</tt></td></tr><tr><td><tt class="literal">sub mygrep (&amp;@)</tt></td><td><tt class="literal">mygrep { /foo/ } $a,$b,$c</tt></td></tr><tr><td><tt class="literal">sub myrand ($)</tt></td><td><tt class="literal">myrand 42</tt></td></tr><tr><td><tt class="literal">sub mytime ()</tt></td><td><tt class="literal">mytime</tt></td></tr></table><p>Any backslashed prototype character (shown between parentheses in theleft column above) represents an actual argument (exemplified in theright column), which absolutely must start with that character.  Just asthe first argument to <tt class="literal">keys</tt> must start with <tt class="literal">%</tt>, so too must thefirst argument to <tt class="literal">mykeys</tt>.</p><p><a name="INDEX-1854"></a><a name="INDEX-1855"></a><a name="INDEX-1856"></a><a name="INDEX-1857"></a><a name="INDEX-1858"></a><a name="INDEX-1859"></a><a name="INDEX-1860"></a>A semicolon separates mandatory arguments from optional arguments.  (Itwould be redundant before <tt class="literal">@</tt> or <tt class="literal">%</tt>, since lists can be null.)Unbackslashed prototype characters have special meanings.  Anyunbackslashed <tt class="literal">@</tt> or <tt class="literal">%</tt> eats all the rest of the actual arguments and forces list context.  (It's equivalent to <em class="replaceable">LIST</em> in a syntaxdescription.)  An argument represented by <tt class="literal">$</tt> has scalar context forced onit.  An <tt class="literal">&amp;</tt> requires a reference to a named or anonymoussubroutine.</p><p><a name="INDEX-1861"></a>A <tt class="literal">*</tt> allows the subroutine to accept anything in that slot that wouldbe accepted by a built-in as a filehandle: a bare name, a constant, ascalar expression, a typeglob, or a reference to a typeglob.  The valuewill be available to the subroutine either as a simple scalar or (inthe latter two cases) as a reference to the typeglob.  If you wish toalways convert such arguments to a typeglob reference, use<tt class="literal">Symbol::qualify_to_ref</tt> as follows:<blockquote><pre class="programlisting">use Symbol 'qualify_to_ref';sub foo (*) {    my $fh = qualify_to_ref(shift, caller);    ...}</pre></blockquote>Note how the last three examples in the table are treatedspecially by the parser.  <tt class="literal">mygrep</tt> is parsed as a true list operator,<tt class="literal">myrand</tt> is parsed as a true unary operator with unary precedencethe same as <tt class="literal">rand</tt>, and <tt class="literal">mytime</tt> is truly argumentless, just like<tt class="literal">time</tt>.</p><p>That is, if you say:<blockquote><pre class="programlisting">mytime +2;</pre></blockquote>you'll get <tt class="literal">mytime() + 2</tt>, not <tt class="literal">mytime(2)</tt>, which is how it would beparsed without the prototype, or with a unary prototype.</p><p>The <tt class="literal">mygrep</tt> example also illustrates how<tt class="literal">&amp;</tt> is treated specially when it is the firstargument. Ordinarily, an <tt class="literal">&amp;</tt> prototype would demandan argument like <tt class="literal">\&amp;foo</tt> or<tt class="literal">sub{}</tt>. When it is the first argument, however, youcan leave off the <tt class="literal">sub</tt> of your anonymous subroutine,and just pass a bare block in the "indirect object" slot (with nocomma after it). So one nifty thing about the <tt class="literal">&amp;</tt>prototype is that you can generate new syntax with it, provided the<tt class="literal">&amp;</tt> is in the initial position:

⌨️ 快捷键说明

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