Project

General

Profile

Actions

Feature #19777

closed

Make `Kernel#lambda` raise when called without a literal block

Added by alanwu (Alan Wu) 10 months ago. Updated 8 months ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:114248]

Description

Since 3.0.0, released in 2020, calling Kernel#lambda without a literal block
has been issuing a deprecation warning:

Warning[:deprecated] = true
def foo(&b) lambda(&b) end
foo {}
# => test.rb:2: warning: lambda without a literal block is deprecated; use the proc without lambda instead

I think enough time has passed and we should make it raise in all situations
where it currently issues a deprecation warning. The original decision to
deprecate is here: https://bugs.ruby-lang.org/issues/15973#note-46

The new behavior allows one to predict whether Kernel#lambda will return by
inspecting its direct caller, checking whether the call site has a literal
block. It will remove some hard-to-predict cases where Kernel#lambda receives
a non-literal block forwarded with super or rb_funcall_passing_block. The
method will always return a lambda, if it returns. However, note that send
will be a special exception in this new model:

Warning[:deprecated] = true

singleton_class.send(:public, :lambda)

p (send(:lambda) {}).lambda?         # => true without warning
p (public_send(:lambda) {}).lambda?  # => true with warning, would raise instead

This newer model is friendlier to some optimization we're investigating for
YJIT as it has fewer moving parts.

Actions

Also available in: Atom PDF

Like1
Like0Like0Like0Like0Like0Like0Like0