Project

General

Profile

Actions

Feature #18831

open

Block argument to `yield`

Added by nobu (Nobuyoshi Nakada) almost 2 years ago. Updated almost 2 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:108931]

Description

Block argument to yield is a syntax error.
This is because there was previously no way to receive a given block in the yielded block.
However do |&block| has been introduced since 1.8.7.
Why is it prohibited still now?

https://github.com/nobu/ruby/tree/blockarg-yield


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #10436: ruby -c and ripper inconsistency: m(&nil) {}ClosedActions
Actions #1

Updated by mame (Yusuke Endoh) almost 2 years ago

  • Related to Bug #10436: ruby -c and ripper inconsistency: m(&nil) {} added

Updated by mame (Yusuke Endoh) almost 2 years ago

We discussed this issue at the dev meeting, and @matz (Yukihiro Matsumoto) was not positive to change it.

Currently, Ruby does not accept yield with a block, but Ripper does. However, it is not trivial to fix Ripper. This issue is strongly related to #10436.

$ ruby -rripper -e 'pp Ripper.sexp("def foo; yield 1, 2, 3 do end; end")'
[:program,
 [[:def,
   [:@ident, "foo", [1, 4]],
   [:params, nil, nil, nil, nil, nil, nil, nil],
   [:bodystmt,
    [[:method_add_block,
      [:yield, [:args_add_block, [[:@int, "1", [1, 15]], [:@int, "2", [1, 18]], [:@int, "3", [1, 21]]], false]],
      [:do_block, nil, [:bodystmt, [[:void_stmt]], nil, nil, nil]]]],
    nil,
    nil,
    nil]]]]

Updated by Eregon (Benoit Daloze) almost 2 years ago

IMHO it would make sense to support it, since Proc#call already supports it.

Updated by mame (Yusuke Endoh) almost 2 years ago

mame (Yusuke Endoh) wrote in #note-2:

@matz (Yukihiro Matsumoto) was not positive to change it.

I forgot to add the reason why he was not positive. @matz (Yukihiro Matsumoto) said he no longer want to make yield so useful. He recommends an explicit Proc#call with a block parameter instead of an implicit block call by yield, especially it passes complex arguments like a block.

def foo(&b)
  b.call(1, 2, 3) do end
end
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0