Feature #19777
closedMake `Kernel#lambda` raise when called without a literal block
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.