Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-04-28T06:32:50ZRuby Issue Tracking System
Redmine Backport193 - Backport #8341 (Closed): block_given? (and the actual block) persist between calls ...https://bugs.ruby-lang.org/issues/83412013-04-28T06:32:50Zpythonesque (Joshua Yanovski)
<p>Confirmed on both 2.0.0 and 1.9.2-p290. A testcase (utilizing RSpec) is attached, but the behavior is easy to demonstrate without a testcase or RSpec.</p>
<p>First, we define a method that can optionally accept a block.<br>
def foo<br>
if block_given?<br>
yield<br>
else<br>
puts "No block given."<br>
end<br>
end</p>
<p>Then, we convert the method to a proc and store it in a variable.<br>
method_to_proc = method(:foo).to_proc</p>
<p>Now, we try calling method_to_proc without a block, getting the expected result:<br>
method_to_proc.call</p>
<a name="gt-No-block-given"></a>
<h1 >=> No block given.<a href="#gt-No-block-given" class="wiki-anchor">¶</a></h1>
<p>We call it again, this time with a block, and again get the expected result:<br>
method_to_proc.call { puts "Block given." }</p>
<a name="gt-Block-given"></a>
<h1 >=> Block given.<a href="#gt-Block-given" class="wiki-anchor">¶</a></h1>
<p>But when we call it a third time, again with no block...<br>
method_to_proc.call</p>
<a name="gt-Block-given-2"></a>
<h1 >=> Block given.<a href="#gt-Block-given-2" class="wiki-anchor">¶</a></h1>
<p>...it remembers the previous proc that was passed in.</p>
<p>If we then call it with a new proc, it overwrites the old proc as expected (this is not tested in the testcase, which only tests block_given?):<br>
method_to_proc.call { puts "New block given." }</p>
<a name="gt-New-block-given"></a>
<h1 >=> New block given.<a href="#gt-New-block-given" class="wiki-anchor">¶</a></h1>
<p>The testcase verifies this behavior, and also that the behavior does not occur when calling a method in the usual way, or when using method() but not to_proc(), or when using method().to_proc() but not storing the result in the same variable (the last of which isn't that surprising but is included for completeness).</p>
<p>I cannot see any reason that this should be expected behavior. Either block_given? should work the same way in method.to_proc()s as it does in method()s, or it should always return false, and it certainly shouldn't "remember" the last block used.</p>