Project

General

Profile

Actions

Bug #12705

closed

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

Added by bughit (bug hit) over 7 years ago. Updated about 7 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 master - Bug #13391: wrong number of arguments error for Hash#map when lambda givenClosedko1 (Koichi Sasada)Actions

Updated by bughit (bug hit) over 7 years ago

a related point is that lambda procs with the same arity (normal_lambda, method_lambda) should behave the same

Updated by bughit (bug hit) over 7 years ago

  • 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) over 7 years ago

  • 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) over 7 years ago

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) over 7 years ago

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) over 7 years ago

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) over 7 years ago

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) over 7 years ago

  • Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: REQUIRED
Actions #9

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

  • Status changed from Assigned to Closed

Applied in changeset r57192.


[Bug #12705]

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

  • Status changed from Closed to Assigned

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

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) about 7 years ago

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) about 7 years ago

  • 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) about 7 years ago

  • 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.

Actions #15

Updated by nobu (Nobuyoshi Nakada) about 7 years ago

  • 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) about 7 years ago

  • 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.

Actions #17

Updated by usa (Usaku NAKAMURA) about 7 years ago

  • Backport changed from 2.2: UNKNOWN, 2.3: REQUIRED, 2.4: DONE to 2.2: REQUIRED, 2.3: REQUIRED, 2.4: DONE
Actions #18

Updated by nobu (Nobuyoshi Nakada) about 7 years ago

  • Related to Bug #13391: wrong number of arguments error for Hash#map when lambda given added
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0