mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Add pipeline operator [Feature #15799]
This commit is contained in:
		
							parent
							
								
									e717d6faa8
								
							
						
					
					
						commit
						f169043d81
					
				
					 6 changed files with 47 additions and 1 deletions
				
			
		
							
								
								
									
										12
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								NEWS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -48,6 +48,18 @@ sufficient information, see the ChangeLog file or Redmine
 | 
			
		|||
     " # This has been warned since 2.4
 | 
			
		||||
     EOS
 | 
			
		||||
 | 
			
		||||
* Pipeline operator is added.
 | 
			
		||||
 | 
			
		||||
  This code equals to the next code.
 | 
			
		||||
 | 
			
		||||
     foo()
 | 
			
		||||
      |> bar 1, 2
 | 
			
		||||
      |> display
 | 
			
		||||
 | 
			
		||||
     foo()
 | 
			
		||||
      .bar(1, 2)
 | 
			
		||||
      .display
 | 
			
		||||
 | 
			
		||||
=== Core classes updates (outstanding ones only)
 | 
			
		||||
 | 
			
		||||
Enumerable::
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,6 +111,7 @@ token_ops = %[\
 | 
			
		|||
  OROP          ||
 | 
			
		||||
  ANDDOT        &.
 | 
			
		||||
  METHREF       .:
 | 
			
		||||
  PIPE          |>
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
class KeywordError < RuntimeError
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -262,6 +262,7 @@ 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)},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								parse.y
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1002,7 +1002,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
 | 
			
		||||
%type <node> expr_value expr_value_do arg_value primary_value fcall rel_expr pipeline
 | 
			
		||||
%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
 | 
			
		||||
| 
						 | 
				
			
			@ -1060,6 +1060,7 @@ 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		"=>"
 | 
			
		||||
| 
						 | 
				
			
			@ -1095,6 +1096,7 @@ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -2269,12 +2271,29 @@ arg		: lhs '=' arg_rhs
 | 
			
		|||
		    /*% %*/
 | 
			
		||||
		    /*% ripper: ifop!($1, $3, $6) %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| pipeline
 | 
			
		||||
		| primary
 | 
			
		||||
		    {
 | 
			
		||||
			$$ = $1;
 | 
			
		||||
		    }
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
pipeline	: arg tPIPE operation2 opt_paren_args
 | 
			
		||||
		    {
 | 
			
		||||
		    /*%%%*/
 | 
			
		||||
			$$ = new_command_qcall(p, ID2VAL(idPIPE), $1, $3, $4, Qnull, &@3, &@$);
 | 
			
		||||
		    /*% %*/
 | 
			
		||||
		    /*% ripper: command_call!($1, ID2VAL(idPIPE), $3, $4) %*/
 | 
			
		||||
		    }
 | 
			
		||||
		| arg tPIPE operation2 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) %*/
 | 
			
		||||
		    }
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
relop		: '>'  {$$ = '>';}
 | 
			
		||||
		| '<'  {$$ = '<';}
 | 
			
		||||
		| tGEQ {$$ = idGE;}
 | 
			
		||||
| 
						 | 
				
			
			@ -8924,6 +8943,10 @@ 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,6 +573,8 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
 | 
			
		|||
                 scan('op', 'obj.:foo')
 | 
			
		||||
    assert_equal [],
 | 
			
		||||
                 scan('op', %q[`make all`])
 | 
			
		||||
    assert_equal %w[|>],
 | 
			
		||||
                 scan('op', %q[x|>y])
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_symbeg
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1379,6 +1379,13 @@ eom
 | 
			
		|||
    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)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def not_label(x) @result = x; @not_label ||= nil end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue