Project

General

Profile

Actions

Feature #10499

closed

Eliminate implicit magic in Proc.new and Kernel#proc

Added by headius (Charles Nutter) almost 10 years ago. Updated almost 4 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 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) almost 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!

Actions #3

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
Actions #4

Updated by naruse (Yui NARUSE) almost 4 years ago

  • Target version deleted (3.0)

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

Actions #7

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]

[Feature #10499]
[Feature #15554]

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

Thank you, updated.

Actions #9

Updated by k0kubun (Takashi Kokubun) 8 months ago

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

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0