Project

General

Profile

Actions

Feature #10499

closed

Eliminate implicit magic in Proc.new and Kernel#proc

Feature #10499: Eliminate implicit magic in Proc.new and Kernel#proc

Added by headius (Charles Nutter) almost 11 years ago. Updated almost 5 years ago.

Status:
Closed
Target version:
-
[ruby-core:66225]

Description

Proc.new and Kernel#proc have a little known feature: if called without a block, they capture whatever block was passed to the current method.

I propose that this feature should be removed, finally, since it:

  • Doesn't enhance readability (where is this block coming from?)
  • Doesn't reflect any other behavior in Ruby
  • Can lead to bugs (call either without a block accidentally and you aren't sure what you'll get)

I believe this was an implementation artifact in MRI, since the most recently-pushed block would still be on global stacks, which is where the logic for proc and Proc.new looked for it.

All argument syntaxes now support &block, which I believe is the correct way to clearly, explicitly capture the incoming block into an object.

Thoughts?

Updated by marcandre (Marc-Andre Lafortune) almost 11 years ago Actions #1 [ruby-core:66228]

  • Category set to core
  • Assignee set to matz (Yukihiro Matsumoto)

I agree.

Deprecate first (2.2?), remove afterwards.

This would also simplify things if and when we want to warn/raise on unused blocks when calling user methods.

Updated by headius (Charles Nutter) almost 11 years ago Actions #2 [ruby-core:66748]

Adding a deprecation warning would be easy if we can get buy-in from matz.

matz: ball's in your court, I think!

Updated by k0kubun (Takashi Kokubun) over 6 years ago Actions #3

  • Copied to Feature #15554: warn/error passing a block to a method which never use a block added

Updated by naruse (Yui NARUSE) almost 5 years ago Actions #4

  • Target version deleted (3.0)

Updated by dazuma (Daniel Azuma) almost 5 years ago Actions #5 [ruby-core:101900]

Was this change implemented in Ruby 3.0.0?

It looks to me like it was. (And this is causing test failures on libraries that depend on this behavior.)

Ruby 2.7.2:

def foo
  Proc.new
end

foo          # => ArgumentError
foo { :hi }  # => Proc

Ruby 3.0.0:

def foo
  Proc.new
end

foo          # => ArgumentError
foo { :hi }  # => ArgumentError

Updated by dazuma (Daniel Azuma) almost 5 years ago Actions #6 [ruby-core:101903]

Note that the documentation still specifies the old behavior in 3.0.0.

Creates a new Proc object, bound to the current context. ::new may be called without a block only within a method with an attached block, in which case that block is converted to the Proc object.

https://ruby-doc.org/core-3.0.0/Proc.html#method-c-new
https://github.com/ruby/ruby/blob/95aff214687a5e12c3eb57d056665741e734c188/proc.c#L800-L813

Updated by nobu (Nobuyoshi Nakada) almost 5 years ago Actions #7

  • Status changed from Open to Closed

Applied in changeset git|8da7f4abc779c6549833d718336d75aac98494b8.


[DOC] Update Proc.new without a block [ci skip]

[Feature #10499]
[Feature #15554]

Updated by nobu (Nobuyoshi Nakada) almost 5 years ago Actions #8 [ruby-core:101905]

Thank you, updated.

Updated by k0kubun (Takashi Kokubun) over 1 year ago Actions #9

  • Copied to deleted (Feature #15554: warn/error passing a block to a method which never use a block)
Actions

Also available in: PDF Atom