<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>cikey (cikey)</title>
    <link>https://ruby-china.org/cikey</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>关于 Proc 与 return 的一个疑问</title>
      <description>&lt;h2 id="看了几篇关于Proc、block和lambda的文章，有一个疑问如下："&gt;看了几篇关于 Proc、block 和 lambda 的文章，有一个疑问如下：&lt;/h2&gt;
&lt;p&gt;先来一段代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f0&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;f0&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# 返回0&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;  &lt;span class="c1"&gt;# 报LocalJumpError: unexpected return&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# 报LocalJumpError: unexpected return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;关于这段的疑问是：不清楚&lt;code&gt;f0&lt;/code&gt;不会报错，但是&lt;code&gt;f1(f2())&lt;/code&gt;报错的根本原因。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;个人感觉是这样——
&lt;code&gt;f1&lt;/code&gt;在&lt;code&gt;p.call&lt;/code&gt;的时候是回到&lt;code&gt;f2&lt;/code&gt;的上下文去执行的。
&lt;code&gt;f2&lt;/code&gt;的上下文还在，这样&lt;code&gt;f1&lt;/code&gt;执行到&lt;code&gt;p.call&lt;/code&gt;的话就相当于直接在方法外&lt;code&gt;f2().call&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yield&lt;/code&gt;也是，相当于直接在&lt;code&gt;f3(){|x| return x}&lt;/code&gt;这个位置的上下文 return，也是在方法外&lt;/p&gt;

&lt;p&gt;&lt;code&gt;return&lt;/code&gt;是方法执行后 return value 给调用方，如果在方法外 return 就没有意义&lt;/p&gt;

&lt;p&gt;不知道这样理解对不对&lt;/p&gt;</description>
      <author>cikey</author>
      <pubDate>Thu, 11 Aug 2016 18:38:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/30803</link>
      <guid>https://ruby-china.org/topics/30803</guid>
    </item>
  </channel>
</rss>
