Feature #17355
openUsing same set of names in or-patterns (pattern matching with Foo(x) | Bar(x))
Description
Given pattern matching is officially supported in Ruby 3, I have an idea about making it more flexible.
Currently, this piece of code produces a syntax error
case [1, 2]
in [1, a] | [a, 3] => a then a
end # duplicated variable name
Duplications don't seem to be a problem here, semantically-wise. We just need to check if all patterns have the same set of names. It's supported in OCaml (also here's an RFC in Rust https://github.com/rust-lang/rust/issues/54883) so I think it can work in Ruby too.
I've been using pattern matching in Ruby since day 1 and it worked great so far. Since I use OCaml daily too I miss this feature every once in a while :)
A more practical example: imagine you have code like this
def user_email(user)
case user
in User(email:) then email
in Admin(email:) then email
in Moderator(email:) then email
end
end
Clearly, it could be simplified if or-patterns were supported:
def user_email(user)
case user
in User(email:) | Admin(email:) | Moderator(email:) then email
end
end
I'd like to know ktsj (Kazuki Tsujimoto)'s thoughts on this.
Updated by Dan0042 (Daniel DeLorme) 4 months ago
Or-patterns are supported, just not with variable assignment. I agree with the request but the title of the ticket is a bit misleading.
But I think the user_email
example actually makes a rather good case for the usefulness of And-patterns:
def user_email(user)
case user
in (User | Admin | Moderator) & {email:} then email
end
end
Updated by decuplet (Nikita Shilnikov) 4 months ago
- Subject changed from Or-patterns (pattern matching like Foo(x) | Bar(x)) to Using same set of names in or-patterns (pattern matching with Foo(x) | Bar(x))
Dan0042 (Daniel DeLorme) wrote in #note-1:
Or-patterns are supported, just not with variable assignment. I agree with the request but the title of the ticket is a bit misleading.
Yeah, thanks, I updated the title.
Dan0042 (Daniel DeLorme) wrote in #note-1:
But I think the
user_email
example actually makes a rather good case for the usefulness of And-patterns:def user_email(user) case user in (User | Admin | Moderator) & {email:} then email end end
Out of curiosity, did you see an example of syntax like that in any other language?
Updated by Dan0042 (Daniel DeLorme) 4 months ago
decuplet (Nikita Shilnikov) wrote in #note-2:
Out of curiosity, did you see an example of syntax like that in any other language?
No I haven't. I briefly mentioned it in #16464#note-2; it just seemed a logical complement to Or-patterns (pun not intended)
Updated by ktsj (Kazuki Tsujimoto) 4 months ago
- Assignee set to ktsj (Kazuki Tsujimoto)
- Status changed from Open to Assigned
I am pretty positive. I will discuss it with Matz after I finish to implement.