Project

General

Profile

Actions

Bug #12705

closed

yielding args to a lambda uses block/proc rather than lambda/method semantics

Bug #12705: yielding 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.

Status:
Closed
Target version:
[ruby-core:77065]

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


Related issues 1 (0 open1 closed)

Related to Ruby - Bug #13391: wrong number of arguments error for Hash#map when lambda givenClosedko1 (Koichi Sasada)Actions

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

Applied in changeset r57192.


[Bug #12705]

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
Actions

Also available in: PDF Atom