From: "palkan (Vladimir Dementyev)" Date: 2021-12-20T12:48:05+00:00 Subject: [ruby-core:106746] [Ruby master Feature#18384] Pattern Match Object Issue #18384 has been updated by palkan (Vladimir Dementyev). baweaver (Brandon Weaver) wrote: > ### Current Viable Workarounds > > It also must be mentioned that this is currently possible: > > ```ruby > list_of_people.select { _1 in { first_name: 'something' } } > ``` In Ruby 3.1, we can omit parens: ```ruby list_of_people.select { _1 in first_name: 'something' | /another/ } ``` Much readable, WDYT? Can we go further and remove _1? (As was mentioned above) ```ruby list_of_people.select { in first_name: 'something' | /another/ } ``` Not sure. And it's not clear how to handle multiline (`do...end`) scenario. The following looks better to me (should we discuss adding `_` as an alias for `_1` again ����?): ```ruby list_of_people.select { _ in first_name: 'something' | /another/ } ``` Omit `in`? ```ruby list_of_people.select { first_name: 'something' | /another/ } ``` Could be confused with a Hash. And multiline is hardly possible. Another thing popped into my mind (the blast from the past): [%p{...}](https://github.com/yakitorii/pattern-match-ruby) ```ruby list_of_people.select(&%p{ first_name: 'something' | /another/ }) ``` I like its explicitness; and simplicity in terms of implementation. But... `&%p{...}`. To sum up, I think, the current syntax is pretty close to ideal: ```ruby list_of_people.select { _1 in first_name: 'something' | /another/ } ``` ---------------------------------------- Feature #18384: Pattern Match Object https://bugs.ruby-lang.org/issues/18384#change-95443 * Author: baweaver (Brandon Weaver) * Status: Open * Priority: Normal ---------------------------------------- Related to discussion in #18369 it might be nice to have a literal syntax for constructing a single pattern match case outside of a one-liner. Years ago in Qo I had done this via `===` to enable syntax like this: ```ruby list_of_people.select(&Qo[first_name: /^F/, last_name: /r$/, age: 20..40]) ``` This is valid Ruby, but the pattern match syntax itself cannot be used outside of a literal match, making this impossible without syntax changes. ### Proposal My proposal would be a case which would be very useful in predicate methods (`any?`, `all?`, etc) and triple-equals responding methods (`select`, `reject`, `grep`, etc): ```ruby list_of_people.select(&pattern( first_name: /^F/, last_name: /r$/, age: 20..40 )) ``` ...in which `pattern` would be substituted with a more appropriate name which I cannot think of at the moment. ### Portability Now the reason I think this could be very interesting is the portability of patterns. Consider the potential of making a `PatternMatch` object much like a Regular Expression: ```ruby TARGET_PERSON = PatternMatch.new(first_name: 'something') list_of_people.select(&TARGET_PERSON) ``` As they can serve similar purposes of giving an expressive language to query against known structures I can see this making sense. The challenge is that the initialization of such an object would need to be special to accommodate the pattern matching syntax, adding more complicated parsing rules. This behavior might be consistent with `Proc`, `RegExp`, and `Range`-like behavior. ### ActiveRecord-like This gets very close to the classic ActiveRecord `where` pattern: ```ruby People.where(age: 20..30) ``` ### Potential Issues Now this is not without potential issue, as must be highlighted. The first, as just mentioned, is the ActiveRecord syntax and potentially overloading that and keyword arguments: ```ruby People.where(age: 20..30) ``` Without a clear signifier this could make parsing much more difficult. ### Current Viable Workarounds It also must be mentioned that this is currently possible: ```ruby list_of_people.select { _1 in { first_name: 'something' } } ``` ...though the requirement of explicit braces feels a tinge verbose, I understand why they're present. I think this is an acceptable compromise at the moment, but feel we're very close to an interesting syntactic breakthrough. -- https://bugs.ruby-lang.org/ Unsubscribe: