perlref.html
来自「perl教程」· HTML 代码 · 共 733 行 · 第 1/5 页
HTML
733 行
<span class="string">'Adam'</span> <span class="operator">=></span> <span class="string">'Eve'</span><span class="operator">,</span>
<span class="string">'Clyde'</span> <span class="operator">=></span> <span class="string">'Bonnie'</span><span class="operator">,</span>
<span class="operator">}</span><span class="operator">;</span>
</pre>
<p>Anonymous hash and array composers like these can be intermixed freely to
produce as complicated a structure as you want. The multidimensional
syntax described below works for these too. The values above are
literals, but variables and expressions would work just as well, because
assignment operators in Perl (even within <a href="../../lib/Pod/perlfunc.html#item_local"><code>local()</code></a> or <a href="../../lib/Pod/perlfunc.html#item_my"><code>my())</code></a> are executable
statements, not compile-time declarations.</p>
<p>Because curly brackets (braces) are used for several other things
including BLOCKs, you may occasionally have to disambiguate braces at the
beginning of a statement by putting a <code>+</code> or a <a href="../../lib/Pod/perlfunc.html#item_return"><code>return</code></a> in front so
that Perl realizes the opening brace isn't starting a BLOCK. The economy and
mnemonic value of using curlies is deemed worth this occasional extra
hassle.</p>
<p>For example, if you wanted a function to make a new hash and return a
reference to it, you have these options:</p>
<pre>
<span class="keyword">sub</span><span class="variable"> hashem </span><span class="operator">{</span> <span class="operator">{</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># silently wrong</span>
<span class="keyword">sub</span><span class="variable"> hashem </span><span class="operator">{</span> <span class="operator">+</span><span class="operator">{</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># ok</span>
<span class="keyword">sub</span><span class="variable"> hashem </span><span class="operator">{</span> <span class="keyword">return</span> <span class="operator">{</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># ok</span>
</pre>
<p>On the other hand, if you want the other meaning, you can do this:</p>
<pre>
<span class="keyword">sub</span><span class="variable"> showem </span><span class="operator">{</span> <span class="operator">{</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># ambiguous (currently ok, but may change)</span>
<span class="keyword">sub</span><span class="variable"> showem </span><span class="operator">{</span> <span class="operator">{</span><span class="operator">;</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># ok</span>
<span class="keyword">sub</span><span class="variable"> showem </span><span class="operator">{</span> <span class="operator">{</span> <span class="keyword">return</span> <span class="variable">@_</span> <span class="operator">}</span> <span class="operator">}</span> <span class="comment"># ok</span>
</pre>
<p>The leading <code>+{</code> and <code>{;</code> always serve to disambiguate
the expression to mean either the HASH reference, or the BLOCK.</p>
</li>
<li><strong></strong>
<p>A reference to an anonymous subroutine can be created by using
<a href="../../lib/Pod/perlfunc.html#item_sub"><code>sub</code></a> without a subname:</p>
<pre>
<span class="variable">$coderef</span> <span class="operator">=</span> <span class="keyword">sub</span><span class="variable"> </span><span class="operator">{</span> <span class="keyword">print</span> <span class="string">"Boink!\n"</span> <span class="operator">};</span>
</pre>
<p>Note the semicolon. Except for the code
inside not being immediately executed, a <a href="../../lib/Pod/perlfunc.html#item_sub"><code>sub {}</code></a> is not so much a
declaration as it is an operator, like <a href="../../lib/Pod/perlfunc.html#item_do"><code>do{}</code></a> or <a href="../../lib/Pod/perlfunc.html#item_eval"><code>eval{}</code></a>. (However, no
matter how many times you execute that particular line (unless you're in an
<a href="../../lib/Pod/perlfunc.html#item_eval"><code>eval("...")</code></a>), $coderef will still have a reference to the <em>same</em>
anonymous subroutine.)</p>
<p>Anonymous subroutines act as closures with respect to <a href="../../lib/Pod/perlfunc.html#item_my"><code>my()</code></a> variables,
that is, variables lexically visible within the current scope. Closure
is a notion out of the Lisp world that says if you define an anonymous
function in a particular lexical context, it pretends to run in that
context even when it's called outside the context.</p>
<p>In human terms, it's a funny way of passing arguments to a subroutine when
you define it as well as when you call it. It's useful for setting up
little bits of code to run later, such as callbacks. You can even
do object-oriented stuff with it, though Perl already provides a different
mechanism to do that--see <a href="../../lib/Pod/perlobj.html">the perlobj manpage</a>.</p>
<p>You might also think of closure as a way to write a subroutine
template without using eval(). Here's a small example of how
closures work:</p>
<pre>
<span class="keyword">sub</span><span class="variable"> newprint </span><span class="operator">{</span>
<span class="keyword">my</span> <span class="variable">$x</span> <span class="operator">=</span> <span class="keyword">shift</span><span class="operator">;</span>
<span class="keyword">return</span> <span class="keyword">sub</span><span class="variable"> </span><span class="operator">{</span> <span class="keyword">my</span> <span class="variable">$y</span> <span class="operator">=</span> <span class="keyword">shift</span><span class="operator">;</span> <span class="keyword">print</span> <span class="string">"$x, $y!\n"</span><span class="operator">;</span> <span class="operator">};</span>
<span class="operator">}</span>
<span class="variable">$h</span> <span class="operator">=</span> <span class="variable">newprint</span><span class="operator">(</span><span class="string">"Howdy"</span><span class="operator">);</span>
<span class="variable">$g</span> <span class="operator">=</span> <span class="variable">newprint</span><span class="operator">(</span><span class="string">"Greetings"</span><span class="operator">);</span>
</pre>
<pre>
<span class="comment"># Time passes...</span>
</pre>
<pre>
<span class="operator">&</span><span class="variable">$h</span><span class="operator">(</span><span class="string">"world"</span><span class="operator">);</span>
<span class="operator">&</span><span class="variable">$g</span><span class="operator">(</span><span class="string">"earthlings"</span><span class="operator">);</span>
</pre>
<p>This prints</p>
<pre>
Howdy, world!
Greetings, earthlings!</pre>
<p>Note particularly that $x continues to refer to the value passed
into <code>newprint()</code> <em>despite</em> "my $x" having gone out of scope by the
time the anonymous subroutine runs. That's what a closure is all
about.</p>
<p>This applies only to lexical variables, by the way. Dynamic variables
continue to work as they have always worked. Closure is not something
that most Perl programmers need trouble themselves about to begin with.</p>
</li>
<li><strong></strong>
<p>References are often returned by special subroutines called constructors.
Perl objects are just references to a special type of object that happens to know
which package it's associated with. Constructors are just special
subroutines that know how to create that association. They do so by
starting with an ordinary reference, and it remains an ordinary reference
even while it's also being an object. Constructors are often
named <code>new()</code> and called indirectly:</p>
<pre>
<span class="variable">$objref</span> <span class="operator">=</span> <span class="variable">new</span> <span class="variable">Doggie</span> <span class="operator">(</span><span class="string">Tail</span> <span class="operator">=></span> <span class="string">'short'</span><span class="operator">,</span> <span class="string">Ears</span> <span class="operator">=></span> <span class="string">'long'</span><span class="operator">);</span>
</pre>
<p>But don't have to be:</p>
<pre>
<span class="variable">$objref</span> <span class="operator">=</span> <span class="variable">Doggie</span><span class="operator">-></span><span class="variable">new</span><span class="operator">(</span><span class="string">Tail</span> <span class="operator">=></span> <span class="string">'short'</span><span class="operator">,</span> <span class="string">Ears</span> <span class="operator">=></span> <span class="string">'long'</span><span class="operator">);</span>
</pre>
<pre>
<span class="keyword">use</span> <span class="variable">Term::Cap</span><span class="operator">;</span>
<span class="variable">$terminal</span> <span class="operator">=</span> <span class="variable">Term::Cap</span><span class="operator">-></span><span class="variable">Tgetent</span><span class="operator">(</span> <span class="operator">{</span> <span class="string">OSPEED</span> <span class="operator">=></span> <span class="number">9600</span> <span class="operator">}</span><span class="operator">);</span>
</pre>
<pre>
<span class="keyword">use</span> <span class="variable">Tk</span><span class="operator">;</span>
<span class="variable">$main</span> <span class="operator">=</span> <span class="variable">MainWindow</span><span class="operator">-></span><span class="variable">new</span><span class="operator">();</span>
<span class="variable">$menubar</span> <span class="operator">=</span> <span class="variable">$main</span><span class="operator">-></span><span class="variable">Frame</span><span class="operator">(</span><span class="string">-relief</span> <span class="operator">=></span> <span class="string">"raised"</span><span class="operator">,</span>
<span class="string">-borderwidth</span> <span class="operator">=></span> <span class="number">2</span><span class="operator">)</span>
</pre>
</li>
<li><strong></strong>
<p>References of the appropriate type can spring into existence if you
dereference them in a context that assumes they exist. Because we haven't
talked about dereferencing yet, we can't show you any examples yet.</p>
</li>
<li><strong></strong>
<p>A reference can be created by using a special syntax, lovingly known as
the *foo{THING} syntax. *foo{THING} returns a reference to the THING
slot in *foo (which is the symbol table entry which holds everything
known as foo).</p>
<pre>
<span class="variable">$scalarref</span> <span class="operator">=</span> <span class="variable">*foo</span><span class="operator">{</span><span class="string">SCALAR</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$arrayref</span> <span class="operator">=</span> <span class="variable">*ARGV</span><span class="operator">{</span><span class="string">ARRAY</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$hashref</span> <span class="operator">=</span> <span class="variable">*ENV</span><span class="operator">{</span><span class="string">HASH</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$coderef</span> <span class="operator">=</span> <span class="variable">*handler</span><span class="operator">{</span><span class="string">CODE</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$ioref</span> <span class="operator">=</span> <span class="variable">*STDIN</span><span class="operator">{</span><span class="string">IO</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$globref</span> <span class="operator">=</span> <span class="variable">*foo</span><span class="operator">{</span><span class="string">GLOB</span><span class="operator">}</span><span class="operator">;</span>
<span class="variable">$formatref</span> <span class="operator">=</span> <span class="variable">*foo</span><span class="operator">{</span><span class="string">FORMAT</span><span class="operator">}</span><span class="operator">;</span>
</pre>
<p>All of these are self-explanatory except for <code>*foo{IO}</code>. It returns
the IO handle, used for file handles (<a href="../../lib/Pod/perlfunc.html#open">open in the perlfunc manpage</a>), sockets
(<a href="../../lib/Pod/perlfunc.html#socket">socket in the perlfunc manpage</a> and <a href="../../lib/Pod/perlfunc.html#socketpair">socketpair in the perlfunc manpage</a>), and directory
handles (<a href="../../lib/Pod/perlfunc.html#opendir">opendir in the perlfunc manpage</a>). For compatibility with previous
versions of Perl, <code>*foo{FILEHANDLE}</code> is a synonym for <code>*foo{IO}</code>, though it
is deprecated as of 5.8.0. If deprecation warnings are in effect, it will warn
of its use.</p>
<p><code>*foo{THING}</code> returns undef if that particular THING hasn't been used yet,
except in the case of scalars. <code>*foo{SCALAR}</code> returns a reference to an
anonymous scalar if $foo hasn't been used yet. This might change in a
future release.</p>
<p><code>*foo{IO}</code> is an alternative to the <code>*HANDLE</code> mechanism given in
<a href="../../lib/Pod/perldata.html#typeglobs_and_filehandles">Typeglobs and Filehandles in the perldata manpage</a> for passing filehandles
into or out of subroutines, or storing into larger data structures.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?