Bug #12705
closedyielding args to a lambda uses block/proc rather than lambda/method semantics
Added by bughit (bug hit) about 9 years ago. Updated over 8 years ago.
Description
def yield_test
yield 1, 2
yield [1, 2]
end
def foo(a, b)
p a, b
end
method_lambda = method(:foo).to_proc
normal_lambda = ->a, b{p a, b}
yield_test(&normal_lambda)
yield_test(&method_lambda)
the yield of [1, 2] to the method_lambda produces an argument error as you would expect
but the same yield to the normal_lamda does not, the single array arg is slpatted per block/proc semantics
Updated by bughit (bug hit) about 9 years ago
Actions
#1
[ruby-core:77066]
a related point is that lambda procs with the same arity (normal_lambda, method_lambda) should behave the same
Updated by bughit (bug hit) about 9 years ago
Actions
#2
[ruby-core:77067]
- Subject changed from yielding args to a lambda uses block/proc rather lambda/method semantics to yielding args to a lambda uses block/proc rather than lambda/method semantics
Updated by shyouhei (Shyouhei Urabe) about 9 years ago
Actions
#3
[ruby-core:77560]
- Status changed from Open to Assigned
- Assignee set to ko1 (Koichi Sasada)
This (stabby lambda not raising exception) is a bug that should be fixed.
Updated by akr (Akira Tanaka) about 9 years ago
Actions
#4
[ruby-core:77563]
lambda should be strict on number of arguments.
So, stabby lambda (and traditional lambda) should not expand
single array argument.
It works until ruby 2.2.
Ruby 2.2 introduce the bug.
% all-ruby -e '
def yield_test
yield [1, 2]
end
normal_lambda = ->a, b{p [a, b] }
yield_test(&normal_lambda)
'
...
ruby-2.1.10 -e:5:in `block in <main>': wrong number of arguments (1 for 2) (ArgumentError)
from -e:3:in `yield_test'
from -e:6:in `<main>'
#<Process::Status: pid 30458 exit 1>
ruby-2.2.0-preview1 [1, 2]
ruby-2.2.0-preview2 [1, 2]
ruby-2.2.0-rc1 [1, 2]
ruby-2.2.0 [1, 2]
ruby-2.2.1 [1, 2]
ruby-2.2.2 [1, 2]
ruby-2.2.3 [1, 2]
ruby-2.2.4 [1, 2]
ruby-2.2.5 [1, 2]
ruby-2.3.0-preview1 [1, 2]
ruby-2.3.0-preview2 [1, 2]
ruby-2.3.0 [1, 2]
ruby-2.3.1 [1, 2]
ruby-2.4.0-preview1 [1, 2]
Updated by bughit (bug hit) about 9 years ago
Actions
#5
[ruby-core:77603]
please also take a look at Bug #12706, it may be related, also has to to with how args are yielded to lambdas
Updated by Eregon (Benoit Daloze) about 9 years ago
Actions
#6
[ruby-core:77634]
This bug seems specific to yield, calling the lambda behaves as expected.
I added specs in ruby/spec to verify this behavior:
https://github.com/ruby/spec/commit/c4cabcf37ac804ea127bd0216c0239e5f9045ec1
The ruby_bug guard can be adjusted as soon as there is a minor release containing the fix for this bug.
Updated by ko1 (Koichi Sasada) almost 9 years ago
Actions
#7
[ruby-core:77907]
This is working memo. Now I can't find out the solution.
(1) auto splat for lambda with yield ary
is allowed [Bug #9605]. So #4 is intentional change.
(2) However, lambda generated by Method#to_proc is not allowed (reported by this ticket)
(3) The reason of (2) is, MRI splat ary only for ISeq level proc (splat at vm_callee_setup_block_arg()
for lambda, called by vm_invoke_iseq_block()
), but bmcall()
(specified by ifunc->func
) doesn't care it.
Possible solution (just now I can make) is vm_invoke_ifunc_block()
checks it, but not clean.
Fundamentally, the spec is not clean, so code should not be clean.
Updated by naruse (Yui NARUSE) almost 9 years ago
Actions
#8
[ruby-core:78843]
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: REQUIRED
Updated by nobu (Nobuyoshi Nakada) almost 9 years ago
Actions
#9
- Status changed from Assigned to Closed
Updated by nobu (Nobuyoshi Nakada) almost 9 years ago
Actions
#10
[ruby-core:79019]
- Status changed from Closed to Assigned
Updated by nobu (Nobuyoshi Nakada) almost 9 years ago
Actions
#11
[ruby-core:79020]
What's the status?
Is the current behavior on a lambda proc is intentional, and has the spec been changed since 2.2?
And is the difference between a method proc and a lambda proc intentional, or not?
If it is unintentional, splat for a method proc too?
Updated by sos4nt (Stefan Schüßler) over 8 years ago
Actions
#12
[ruby-core:79269]
I encountered this bug myself today and while searching for a reason behind it, I found this:
https://github.com/ruby/ruby/blob/v2_4_0/vm_insnhelper.c#L2435
static VALUE
vm_yield_with_cfunc(rb_thread_t *th,
const struct rb_captured_block *captured,
VALUE self, int argc, const VALUE *argv, VALUE block_handler)
{
int is_lambda = FALSE; /* TODO */
That static FALSE
value doesn't look right ...
Updated by ko1 (Koichi Sasada) over 8 years ago
Actions
#13
[ruby-core:79333]
- Assignee changed from ko1 (Koichi Sasada) to nobu (Nobuyoshi Nakada)
Nobu and I discussed about this issue and Nobu is trying to fix this issue by simplify lambda arg spec.
Updated by shyouhei (Shyouhei Urabe) over 8 years ago
Actions
#14
[ruby-core:80134]
- Target version set to 2.5
We looked at this issue in today's developer meeting and Koichi said he want this be fixed in 2.5.
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
Actions
#15
- Status changed from Assigned to Closed
Applied in changeset r58019.
vm_args.c: arity check of lambda
-
vm_eval.c (rb_yield_lambda): new function which yields an array
to a proc and splat to a lambda. mainly for Enumerable only. -
vm_args.c (setup_parameters_complex): remove special lambda
splatting for [Bug #9605]. [ruby-core:77065] [Bug #12705] -
vm_insnhelper.c (vm_callee_setup_block_arg): ditto.
Updated by naruse (Yui NARUSE) over 8 years ago
Actions
#16
[ruby-core:80265]
- Backport changed from 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: REQUIRED to 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: DONE
ruby_2_4 r58045 merged revision(s) 57192,57464,58016,58018,58019.
Updated by usa (Usaku NAKAMURA) over 8 years ago
Actions
#17
- Backport changed from 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: DONE to 2.2: REQUIRED, 2.3: REQUIRED, 2.4: DONE
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
Actions
#18
- Related to Bug #13391: wrong number of arguments error for Hash#map when lambda given added