Project

General

Profile

Actions

Backport #8341

closed

block_given? (and the actual block) persist between calls to a proc created from a method (using method().to_proc()).

Added by pythonesque (Joshua Yanovski) over 11 years ago. Updated over 11 years ago.

Status:
Closed
[ruby-core:54626]

Description

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.

First, we define a method that can optionally accept a block.
def foo
if block_given?
yield
else
puts "No block given."
end
end

Then, we convert the method to a proc and store it in a variable.
method_to_proc = method(:foo).to_proc

Now, we try calling method_to_proc without a block, getting the expected result:
method_to_proc.call

=> No block given.

We call it again, this time with a block, and again get the expected result:
method_to_proc.call { puts "Block given." }

=> Block given.

But when we call it a third time, again with no block...
method_to_proc.call

=> Block given.

...it remembers the previous proc that was passed in.

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?):
method_to_proc.call { puts "New block given." }

=> New block given.

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).

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.


Files

testcase.rb (1.67 KB) testcase.rb pythonesque (Joshua Yanovski), 04/28/2013 06:32 AM
8341.patch (2.32 KB) 8341.patch ktsj (Kazuki Tsujimoto), 06/16/2013 03:29 AM

Related issues 1 (0 open1 closed)

Related to Backport193 - Backport #8531: ifuncに渡したブロックが共有されるClosedusa (Usaku NAKAMURA)06/16/2013Actions

Updated by ktsj (Kazuki Tsujimoto) over 11 years ago

bmcall'(ifunc) should use a block set by vm_yield_with_cfunc' instead of PASSED_BLOCK.
I attached a patch.

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

  • Category set to core
  • Assignee changed from ko1 (Koichi Sasada) to ktsj (Kazuki Tsujimoto)

LTGM

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

  • Status changed from Open to Assigned
Actions #4

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r41342.
Joshua, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


test/ruby/test_proc.rb: tests for [Bug #8341]

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

  • Status changed from Closed to Assigned
  • % Done changed from 100 to 0
  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN to 1.9.3: REQUIRED, 2.0.0: REQUIRED
Actions #6

Updated by ktsj (Kazuki Tsujimoto) over 11 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r41359.
Joshua, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • include/ruby/intern.h, proc.c (rb_method_call_with_block):
    new function to invoke a Method object with a block passed
    as an argument.

  • proc.c (bmcall): use the above function to avoid a block sharing.
    [ruby-core:54626] [Bug #8341]

  • test/ruby/test_proc.rb (TestProc#test_block_persist_between_calls):
    run related tests.

Actions #7

Updated by ktsj (Kazuki Tsujimoto) over 11 years ago

  • Tracker changed from Bug to Backport
  • Project changed from Ruby master to Backport200
  • Category deleted (core)
  • Status changed from Closed to Assigned
  • Assignee changed from ktsj (Kazuki Tsujimoto) to nagachika (Tomoyuki Chikanaga)

Please backport r41342, r41359.

Updated by ktsj (Kazuki Tsujimoto) over 11 years ago

Oops, r41361 is also needed.

Actions #9

Updated by nagachika (Tomoyuki Chikanaga) over 11 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r41392.
Joshua, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 41342,41359,41361: [Backport #8341]

test/ruby/test_proc.rb: tests for [Bug #8341]
* include/ruby/intern.h, proc.c (rb_method_call_with_block):
  new function to invoke a Method object with a block passed
  as an argument.

* proc.c (bmcall): use the above function to avoid a block sharing.
  [ruby-core:54626] [Bug #8341]

* test/ruby/test_proc.rb (TestProc#test_block_persist_between_calls):
  run related tests.

* test/ruby/test_proc.rb (TestProc#test_block_given_method_to_proc):
  run test for r41359.
Actions #10

Updated by nagachika (Tomoyuki Chikanaga) over 11 years ago

  • Project changed from Backport200 to Backport193
  • Status changed from Closed to Assigned
  • Assignee changed from nagachika (Tomoyuki Chikanaga) to usa (Usaku NAKAMURA)
Actions #11

Updated by usa (Usaku NAKAMURA) over 11 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r41650.
Joshua, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 41342,41359,41361: [Backport #8341]

test/ruby/test_proc.rb: tests for [Bug #8341]
* include/ruby/intern.h, proc.c (rb_method_call_with_block):
  new function to invoke a Method object with a block passed
  as an argument.

* proc.c (bmcall): use the above function to avoid a block sharing.
  [ruby-core:54626] [Bug #8341]

* test/ruby/test_proc.rb (TestProc#test_block_persist_between_calls):
  run related tests.

* test/ruby/test_proc.rb (TestProc#test_block_given_method_to_proc):
  run test for r41359.
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0