summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-11-18 12:44:19 -0800
committerJeremy Evans <code@jeremyevans.net>2021-11-18 14:17:57 -0800
commit4adb012926f8bd6011168327d8832cf19976de40 (patch)
tree9457020694002d0a0c07ced988a1d09c79fa74e6 /parse.y
parentea02b93bb95a42439631606269659dffc1981883 (diff)
Anonymous block forwarding allows a method to forward a passed
block to another method without having to provide a name for the block parameter. Implements [Feature #11256] Co-authored-by: Yusuke Endoh mame@ruby-lang.org Co-authored-by: Nobuyoshi Nakada nobu@ruby-lang.org
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5051
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y21
1 files changed, 21 insertions, 0 deletions
diff --git a/parse.y b/parse.y
index 8bfb7f2757..b6498651bf 100644
--- a/parse.y
+++ b/parse.y
@@ -427,6 +427,8 @@ static void token_info_drop(struct parser_params *p, const char *token, rb_code_
#define lambda_beginning_p() (p->lex.lpar_beg == p->lex.paren_nest)
+#define ANON_BLOCK_ID '&'
+
static enum yytokentype yylex(YYSTYPE*, YYLTYPE*, struct parser_params*);
#ifndef RIPPER
@@ -2846,6 +2848,17 @@ block_arg : tAMPER arg_value
/*% %*/
/*% ripper: $2 %*/
}
+ | tAMPER
+ {
+ /*%%%*/
+ if (!local_id(p, ANON_BLOCK_ID)) {
+ compile_error(p, "no anonymous block parameter");
+ }
+ $$ = NEW_BLOCK_PASS(NEW_LVAR(ANON_BLOCK_ID, &@1), &@$);
+ /*%
+ $$ = Qnil;
+ %*/
+ }
;
opt_block_arg : ',' block_arg
@@ -5541,6 +5554,14 @@ f_block_arg : blkarg_mark tIDENTIFIER
/*% %*/
/*% ripper: blockarg!($2) %*/
}
+ | blkarg_mark
+ {
+ /*%%%*/
+ arg_var(p, shadowing_lvar(p, get_id(ANON_BLOCK_ID)));
+ /*%
+ $$ = dispatch1(blockarg, Qnil);
+ %*/
+ }
;
opt_f_block_arg : ',' f_block_arg