Project

General

Profile

Actions

Feature #15824

open

respond_to pattern for pattern match

Added by fukajun (Jun Fukaya) about 2 years ago. Updated over 1 year ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:92540]

Description

rubyに追加されそうなパターンマッチの機能について...
Interger, Array など constantを書くことで、オブジェクトのクラスにマッチングさせる機能があるのを拝見しました。
duck typingを確認するようなパターンマッチがかけるとrubyらしいのではないかと思ってこちらに書いてみることにしました。

respond_to pattern

class Runner
  def run
  end

  def stop
  end
end

runner = Runner.new
case runner
in .run & .stop
  :reachable
in .start & .stop
  :unreachable
end 

Related issues

Related to Ruby master - Feature #14912: Introduce pattern matching syntaxClosedktsj (Kazuki Tsujimoto)Actions

Updated by shevegen (Robert A. Heiler) about 2 years ago

I don't want to comment so much on the issue as such, but I would like to point
out that it may be a better idea to start with a new idea not on highest
complexity. I am not sure if everyone fully understood pattern matching yet so
in my personal opinion it may be better to see how pattern matching is used
before making it more complex (including syntactic changes). But that's just
my opinion, anyway; some of the syntax appears to become no longer recognizable
ruby (to me).

Updated by matz (Yukihiro Matsumoto) about 2 years ago

Interesting idea. We need to investigate the idea further.

Matz.

Actions #3

Updated by ktsj (Kazuki Tsujimoto) about 2 years ago

Updated by wanabe (_ wanabe) over 1 year ago

The implementation can be very simple.
(I don't know whether NODE_METHREF is suitable.)

diff --git a/compile.c b/compile.c
index 7a88f81daa..f6eafb0ac2 100644
--- a/compile.c
+++ b/compile.c
@@ -5888,6 +5888,11 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
         ADD_LABEL(ret, fin);
         break;
       }
+      case NODE_METHREF: {
+        ADD_INSN1(ret, line, putobject, ID2SYM(node->nd_mid));
+        ADD_SEND(ret, line, idRespond_to, INT2FIX(1));
+        break;
+      }
       default:
         UNKNOWN_NODE("NODE_IN", node, COMPILE_NG);
     }
diff --git a/parse.y b/parse.y
index 287704e14f..dd305479f5 100644
--- a/parse.y
+++ b/parse.y
@@ -3904,6 +3904,10 @@ p_expr_basic     : p_value
                    {
                        $$ = $2;
                    }
+                | '.' operation2
+                    {
+                       $$ = NEW_METHREF(Qundef, $2, &@$);
+                    }
                ;

 p_args         : p_expr

By the way, missing "& pattern" seems to be intended. see [ruby-core:88036] https://bugs.ruby-lang.org/issues/14912#note-7 .

Actions

Also available in: Atom PDF