Feature #10499
closedEliminate implicit magic in Proc.new and Kernel#proc
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) about 10 years ago
- 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) about 10 years ago
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 5 years ago
- Copied to Feature #15554: warn/error passing a block to a method which never use a block added
Updated by dazuma (Daniel Azuma) almost 4 years ago
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 4 years ago
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 4 years ago
- Status changed from Open to Closed
Applied in changeset git|8da7f4abc779c6549833d718336d75aac98494b8.
[DOC] Update Proc.new without a block [ci skip]
Updated by nobu (Nobuyoshi Nakada) almost 4 years ago
Thank you, updated.
Updated by k0kubun (Takashi Kokubun) 9 months ago
- Copied to deleted (Feature #15554: warn/error passing a block to a method which never use a block)