[#92063] [Ruby trunk Misc#15723] Reconsider numbered parameters — zverok.offline@...
Issue #15723 has been updated by zverok (Victor Shepelev).
3 messages
2019/03/31
[ruby-core:91708] [Ruby trunk Bug#15620] Block argument usage affects lambda semantic
From:
eregontp@...
Date:
2019-03-07 14:57:44 UTC
List:
ruby-core #91708
Issue #15620 has been updated by Eregon (Benoit Daloze).
`lambda(&proc{}).lambda?` returns false because I think the rule is:
once a Proc is created, it never changes its lambda-ness.
So the only way to create a lambda is passing a block directly to `lambda` (or through `send`), or using `->`.
So I think `direct_pass` above should create a non-lambda Proc, and I would argue it's a bug it creates a lambda since MRI 2.5.
----------------------------------------
Bug #15620: Block argument usage affects lambda semantic
https://bugs.ruby-lang.org/issues/15620#change-76978
* Author: alanwu (Alan Wu)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version:
* ruby -v:
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
The following snippet demonstrate the issue:
``` ruby
def pass_after_use(&block)
raise unless block
lambda(&block).call
end
def direct_pass(&block)
lambda(&block).call
end
pass_after_use do |_arg|
puts "fine, because block is materialized into a Proc before it is passed to #lambda"
end
direct_pass do |_arg|
puts "Raises because all args are required. This is not printed"
end
```
Output:
```
fine, because block is materialized into a Proc before it is passed to #lambda
Traceback (most recent call last):
2: from lambda-block-pass.rb:14:in `<main>'
1: from lambda-block-pass.rb:7:in `direct_pass'
lambda-block-pass.rb:14:in `block in <main>': wrong number of arguments (given 0, expected 1) (ArgumentError)
```
I think having the line `raise unless block` affect `Kenrel#lambda`'s semantic is pretty surprising. Note that if I do `raise unless block_given?`, call to the lambda without arg also raises.
If I was to decide, I would always have the resulting lambda have required arguments even after multiple levels of block pass. That is, as long as the original block is a literal block.
This is either a breaking change or a regression from 2.4. The same script executes without raising in 2.4.5 (block arguments are always materialized).
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>