Skip to content
Permalink
Browse files

Revert "Add pipeline operator [Feature #15799]"

This reverts commits:
* d365fd5
* d780c36
* aa72118
* 043f010
* bb4dd7c6af05c7821d572e2592ea3d0cc748d81f
* 043f010
* f169043

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/94645
  • Loading branch information...
nobu committed Aug 29, 2019
1 parent 893900d commit 2ed68d0ff9a932efbc4393c869534040dec8f647
Showing with 2 additions and 64 deletions.
  1. +0 −11 NEWS
  2. +0 −1 defs/id.def
  3. +0 −1 ext/ripper/eventids2.c
  4. +2 −40 parse.y
  5. +0 −2 test/ripper/test_scanner_events.rb
  6. +0 −9 test/ruby/test_syntax.rb
11 NEWS
@@ -48,17 +48,6 @@ sufficient information, see the ChangeLog file or Redmine
" # This has been warned since 2.4
EOS

* Pipeline operator is experimentally added.

This code equals to the next code.

foo()
|> bar 1, 2
|> display

foo()
.bar(1, 2)
.display

* The flip-flop syntax deprecation is reverted. [Feature #5400]

@@ -117,7 +117,6 @@ token_ops = %[\
OROP ||
ANDDOT &.
METHREF .:
PIPE |>
]

class KeywordError < RuntimeError
@@ -262,7 +262,6 @@ static const struct token_assoc {
{tDSTAR, O(op)},
{tANDDOT, O(op)},
{tMETHREF, O(op)},
{tPIPE, O(op)},
{tSTRING_BEG, O(tstring_beg)},
{tSTRING_CONTENT, O(tstring_content)},
{tSTRING_DBEG, O(embexpr_beg)},
42 parse.y
@@ -1009,7 +1009,7 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
%type <node> literal numeric simple_numeric ssym dsym symbol cpath
%type <node> top_compstmt top_stmts top_stmt begin_block
%type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr pipeline
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
%type <node> args call_args opt_call_args
%type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
@@ -1067,7 +1067,6 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
%token <id> tANDDOT RUBY_TOKEN(ANDDOT) "&."
%token <id> tCOLON2 RUBY_TOKEN(COLON2) "::"
%token <id> tMETHREF RUBY_TOKEN(METHREF) ".:"
%token tPIPE RUBY_TOKEN(PIPE) "|>"
%token tCOLON3 ":: at EXPR_BEG"
%token <id> tOP_ASGN "operator-assignment" /* +=, -= etc. */
%token tASSOC "=>"
@@ -1103,7 +1102,6 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
%nonassoc modifier_if modifier_unless modifier_while modifier_until
%left keyword_or keyword_and
%right keyword_not
%left tPIPE
%nonassoc keyword_defined
%right '=' tOP_ASGN
%left modifier_rescue
@@ -1512,37 +1510,6 @@ expr : command_call
$$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
}
| arg
| pipeline
;

pipeline : expr tPIPE operation opt_paren_args
{
/*%%%*/
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, Qnull, &@3, &@$);
/*% %*/
/*% ripper: command_call!($1, ID2VAL(idPIPE), $3, $4) %*/
}
| expr tPIPE operation opt_paren_args brace_block
{
/*%%%*/
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, $5, &@3, &@$);
/*% %*/
/*% ripper: method_add_block!(command_call!($1, ID2VAL(idPIPE), $3, $4), $5) %*/
}
| expr tPIPE operation command_args
{
/*%%%*/
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, Qnull, &@3, &@$);
/*% %*/
/*% ripper: command_call!($1, ID2VAL(idPIPE), $3, $4) %*/
}
| expr tPIPE operation command_args do_block
{
/*%%%*/
$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, $5, &@3, &@$);
/*% %*/
/*% ripper: method_add_block!(command_call!($1, ID2VAL(idPIPE), $3, $4), $5) %*/
}
;

expr_value : expr
@@ -8710,11 +8677,10 @@ parser_yylex(struct parser_params *p)
case '\13': /* '\v' */
space_seen = 1;
break;
case '|':
case '&':
case '.': {
dispatch_delayed_token(p, tIGNORED_NL);
if (c == '|' ? peek(p, '>') : (peek(p, '.') == (c == '&'))) {
if (peek(p, '.') == (c == '&')) {
pushback(p, c);
dispatch_scan_event(p, tSP);
goto retry;
@@ -8989,10 +8955,6 @@ parser_yylex(struct parser_params *p)
SET_LEX_STATE(EXPR_BEG);
return tOP_ASGN;
}
if (c == '>') {
SET_LEX_STATE(EXPR_DOT);
return tPIPE;
}
SET_LEX_STATE(IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL);
pushback(p, c);
return '|';
@@ -573,8 +573,6 @@ def test_op
scan('op', 'obj.:foo')
assert_equal [],
scan('op', %q[`make all`])
assert_equal %w[|>],
scan('op', %q[x|>y])
end

def test_symbeg
@@ -1388,15 +1388,6 @@ def test_numbered_parameter
assert_syntax_error('@1', /outside block/)
end

def test_pipeline_operator
assert_valid_syntax('x |> y')
x = nil
assert_equal("121", eval('x = 12 |> pow(2) |> to_s 11'))
assert_equal(12, x)
assert_equal([2, 4, 6], eval("1.. |> take 3\n|> map do @1 * 2 end"))
assert_syntax_error('a|>-b', /unexpected '-'/)
end

def test_value_expr_in_condition
mesg = /void value expression/
assert_syntax_error("tap {a = (true ? next : break)}", mesg)

7 comments on commit 2ed68d0

@ahmgeek

This comment has been minimized.

Copy link

replied Sep 5, 2019

🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉

@joelibaceta

This comment has been minimized.

Copy link

replied Sep 5, 2019

🤔

@dux

This comment has been minimized.

Copy link

replied Sep 5, 2019

why so happy :) ?

@Shamash2014

This comment has been minimized.

Copy link

replied Sep 5, 2019

🤔

@keyboard-clacker

This comment has been minimized.

Copy link

replied Sep 5, 2019

For what it's worth, I feel like an actual pipeline operator isn't contentious. This as implemented is not a pipeline operator, it's pretty much just chaining method calls, not piping the result of one expression into the arguments of another function.
Example:

# method chaining:
foo()
 .bar(1, 2)
 .display

# piping:
foo() |> format |> puts

In this case, format and puts are not methods on whatever's returned from foo, but their own functions.

@andrelip

This comment has been minimized.

Copy link

replied Sep 5, 2019

bad news

@clemens

This comment has been minimized.

Copy link

replied Sep 5, 2019

Good news that its current form was removed. Sad that a proper implementation (like in Elixir) didn't (yet) make it instead.

Please sign in to comment.
You can’t perform that action at this time.