[前][次][番号順一覧][スレッド一覧]

ruby-changes:63444

From: Nobuyoshi <ko1@a...>
Date: Mon, 26 Oct 2020 18:00:51 +0900 (JST)
Subject: [ruby-changes:63444] 52c630da00 (master): Assoc pattern matching (#3703)

https://git.ruby-lang.org/ruby.git/commit/?id=52c630da00

From 52c630da004d9273e8e5fc91c6304e9eed902566 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Mon, 26 Oct 2020 18:00:24 +0900
Subject: Assoc pattern matching (#3703)

[Feature #17260] One-line pattern matching using tASSOC

R-assignment is rejected instead.

diff --git a/parse.y b/parse.y
index f8d05ad..85cb671 100644
--- a/parse.y
+++ b/parse.y
@@ -1150,7 +1150,7 @@ static int looking_at_eol_p(struct parser_params *p); https://github.com/ruby/ruby/blob/trunk/parse.y#L1150
 %type <node> string_contents xstring_contents regexp_contents string_content
 %type <node> words symbols symbol_list qwords qsymbols word_list qword_list qsym_list word
 %type <node> literal numeric simple_numeric ssym dsym symbol cpath def_name defn_head defs_head
-%type <node> top_compstmt top_stmts top_stmt begin_block rassign
+%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> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
@@ -1242,7 +1242,7 @@ static int looking_at_eol_p(struct parser_params *p); https://github.com/ruby/ruby/blob/trunk/parse.y#L1242
 %nonassoc tLOWEST
 %nonassoc tLBRACE_ARG
 
-%nonassoc  modifier_if modifier_unless modifier_while modifier_until keyword_in
+%nonassoc  modifier_if modifier_unless modifier_while modifier_until
 %left  keyword_or keyword_and
 %right keyword_not
 %nonassoc keyword_defined
@@ -1548,40 +1548,9 @@ stmt		: keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem https://github.com/ruby/ruby/blob/trunk/parse.y#L1548
 		    /*% %*/
 		    /*% ripper: massign!($1, $3) %*/
 		    }
-		| rassign
 		| expr
 		;
 
-rassign 	: arg_value tASSOC lhs
-		    {
-		    /*%%%*/
-			$$ = node_assign(p, $3, $1, &@$);
-		    /*% %*/
-		    /*% ripper: assign!($3, $1) %*/
-		    }
-		| arg_value tASSOC mlhs
-		    {
-		    /*%%%*/
-			$$ = node_assign(p, $3, $1, &@$);
-		    /*% %*/
-		    /*% ripper: massign!($3, $1) %*/
-		    }
-		| rassign tASSOC lhs
-		    {
-		    /*%%%*/
-			$$ = node_assign(p, $3, $1, &@$);
-		    /*% %*/
-		    /*% ripper: assign!($3, $1) %*/
-		    }
-		| rassign tASSOC mlhs
-		    {
-		    /*%%%*/
-			$$ = node_assign(p, $3, $1, &@$);
-		    /*% %*/
-		    /*% ripper: massign!($3, $1) %*/
-		    }
-		;
-
 command_asgn	: lhs '=' command_rhs
 		    {
 		    /*%%%*/
@@ -1677,7 +1646,7 @@ expr		: command_call https://github.com/ruby/ruby/blob/trunk/parse.y#L1646
 		    {
 			$$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
 		    }
-		| arg keyword_in
+		| arg tASSOC
 		    {
 			value_expr($1);
 			SET_LEX_STATE(EXPR_BEG|EXPR_LABEL);
diff --git a/spec/ruby/command_line/dash_upper_w_spec.rb b/spec/ruby/command_line/dash_upper_w_spec.rb
index 8343bc0..2b617f9 100644
--- a/spec/ruby/command_line/dash_upper_w_spec.rb
+++ b/spec/ruby/command_line/dash_upper_w_spec.rb
@@ -32,10 +32,10 @@ ruby_version_is "2.7" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/command_line/dash_upper_w_spec.rb#L32
 
   describe "The -W command line option with :no-experimental" do
     it "suppresses experimental warnings" do
-      result = ruby_exe('0 in a', args: '2>&1')
+      result = ruby_exe('case 0; in a; end', args: '2>&1')
       result.should =~ /is experimental/
 
-      result = ruby_exe('0 in a', options: '-W:no-experimental', args: '2>&1')
+      result = ruby_exe('case 0; in a; end', options: '-W:no-experimental', args: '2>&1')
       result.should == ""
     end
   end
diff --git a/spec/ruby/command_line/rubyopt_spec.rb b/spec/ruby/command_line/rubyopt_spec.rb
index ee4e594..a739f23 100644
--- a/spec/ruby/command_line/rubyopt_spec.rb
+++ b/spec/ruby/command_line/rubyopt_spec.rb
@@ -68,13 +68,13 @@ describe "Processing RUBYOPT" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/command_line/rubyopt_spec.rb#L68
 
     it "suppresses experimental warnings for '-W:no-experimental'" do
       ENV["RUBYOPT"] = '-W:no-experimental'
-      result = ruby_exe('0 in a', args: '2>&1')
+      result = ruby_exe('case 0; in a; end', args: '2>&1')
       result.should == ""
     end
 
     it "suppresses deprecation and experimental warnings for '-W:no-deprecated -W:no-experimental'" do
       ENV["RUBYOPT"] = '-W:no-deprecated -W:no-experimental'
-      result = ruby_exe('($; = "") in a', args: '2>&1')
+      result = ruby_exe('case ($; = ""); in a; end', args: '2>&1')
       result.should == ""
     end
   end
diff --git a/spec/ruby/core/warning/element_set_spec.rb b/spec/ruby/core/warning/element_set_spec.rb
index ee83656..a6b2828 100644
--- a/spec/ruby/core/warning/element_set_spec.rb
+++ b/spec/ruby/core/warning/element_set_spec.rb
@@ -8,8 +8,8 @@ ruby_version_is '2.7' do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/warning/element_set_spec.rb#L8
     end
 
     it "emits and suppresses warnings for :experimental" do
-      ruby_exe('Warning[:experimental] = true; eval("0 in a")', args: "2>&1").should =~ /is experimental/
-      ruby_exe('Warning[:experimental] = false; eval("0 in a")', args: "2>&1").should == ""
+      ruby_exe('Warning[:experimental] = true; eval("case 0; in a; end")', args: "2>&1").should =~ /is experimental/
+      ruby_exe('Warning[:experimental] = false; eval("case 0; in a; end")', args: "2>&1").should == ""
     end
 
     it "raises for unknown category" do
diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb
index 91ad23b..2d22ec7 100644
--- a/spec/ruby/language/pattern_matching_spec.rb
+++ b/spec/ruby/language/pattern_matching_spec.rb
@@ -9,11 +9,13 @@ ruby_version_is "2.7" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/language/pattern_matching_spec.rb#L9
       ScratchPad.record []
     end
 
-    it "can be standalone in operator that deconstructs value" do
-      eval(<<-RUBY).should == [0, 1]
-        [0, 1] in [a, b]
-        [a, b]
-      RUBY
+    ruby_version_is "3.0" do
+      it "can be standalone assoc operator that deconstructs value" do
+        eval(<<-RUBY).should == [0, 1]
+          [0, 1] => [a, b]
+          [a, b]
+        RUBY
+      end
     end
 
     it "extends case expression with case/in construction" do
diff --git a/test/ripper/test_sexp.rb b/test/ripper/test_sexp.rb
index 47339ba..87b505a 100644
--- a/test/ripper/test_sexp.rb
+++ b/test/ripper/test_sexp.rb
@@ -412,7 +412,7 @@ eot https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L412
       [:@int, "0", [1, 5]],
       [:in, [:aryptn, nil, nil, nil, nil], [[:void_stmt]], nil]],
 
-    [__LINE__, %q{ 0 in [*, a, *] }] =>
+    [__LINE__, %q{ 0 => [*, a, *] }] =>
     [:case,
       [:@int, "0", [1, 0]],
       [:in,
@@ -424,7 +424,7 @@ eot https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L424
         nil,
         nil]],
 
-    [__LINE__, %q{ 0 in [*a, b, *c] }] =>
+    [__LINE__, %q{ 0 => [*a, b, *c] }] =>
     [:case,
       [:@int, "0", [1, 0]],
       [:in,
@@ -436,7 +436,7 @@ eot https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L436
         nil,
         nil]],
 
-    [__LINE__, %q{ 0 in A(*a, b, c, *d) }] =>
+    [__LINE__, %q{ 0 => A(*a, b, c, *d) }] =>
     [:case,
       [:@int, "0", [1, 0]],
       [:in,
diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb
index e5a18c5..d4de685 100644
--- a/test/ruby/test_pattern_matching.rb
+++ b/test/ruby/test_pattern_matching.rb
@@ -272,7 +272,7 @@ class TestPatternMatching < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pattern_matching.rb#L272
     end
 
     assert_syntax_error(%q{
-      0 in [a, a]
+      0 => [a, a]
     }, /duplicated variable name/)
   end
 
@@ -737,10 +737,10 @@ END https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pattern_matching.rb#L737
   end
 
   def test_find_pattern
-    [0, 1, 2] in [*, 1 => a, *]
+    [0, 1, 2] => [*, 1 => a, *]
     assert_equal(1, a)
 
-    [0, 1, 2] in [*a, 1 => b, *c]
+    [0, 1, 2] => [*a, 1 => b, *c]
     assert_equal([0], a)
     assert_equal(1, b)
     assert_equal([2], c)
@@ -763,7 +763,7 @@ END https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pattern_matching.rb#L763
       end
     end
 
-    [0, 1, 2] in [*a, 1 => b, 2 => c, *d]
+    [0, 1, 2] => [*a, 1 => b, 2 => c, *d]
     assert_equal([0], a)
     assert_equal(1, b)
     assert_equal(2, c)
@@ -1451,18 +1451,18 @@ END https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pattern_matching.rb#L1451
 
   ################################################################
 
-  def test_modifier_in
-    1 in a
+  def test_assoc
+    1 => a
     assert_equal 1, a
     assert_raise(NoMatchingPatternError) do
-      {a: 1} in {a: 0}
+      {a: 1} => {a: 0}
     end
-    assert_syntax_error("if {} in {a:}; end", /void value expression/)
+    assert_syntax_error("if {} => {a:}; end", /void value expression/)
     assert_syntax_error(%q{
-      1 in a, b
+      1 => a, b
     }, /unexpected/, '[ruby-core:95098]')
     assert_syntax_error(%q{
-      1 in a:
+      1 => a:
     }, /unexpected/, '[ruby-core:95098]')
   end
 
@@ -1480,7 +1480,7 @@ END https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pattern_matching.rb#L1480
 
   def test_experimental_warning
     assert_experimental_warning("case 0; in 0; end")
-    assert_experimental_warning("0 in 0")
+    assert_experimental_warning("0 => 0")
   end
 end
 END_of_GUARD
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 2e0d306..0a370d4 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1430,8 +1430,6 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L1430
     assert_syntax_error('private def obj.foo = 42', /unexpected '='/)
     assert_valid_syntax('private def obj.foo() = 42')
     assert_valid_syntax('private def obj.inc(x) = x + 1')
-    eval('def self.inc(x) (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]