[ruby-dev:52196] [Ruby Feature#21857] Introduce to_proc pattern
Issue #21857 has been reported by sanfrecce-osaka (Masatoshi Moritsuka). ---------------------------------------- Feature #21857: Introduce to_proc pattern https://bugs.ruby-lang.org/issues/21857 * Author: sanfrecce-osaka (Masatoshi Moritsuka) * Status: Open ---------------------------------------- When object has some logics, we can use `&object` syntax with Enumerable or Array, etc. ```ruby users.any?(&:admin?) ``` There are some times when I want to write pattern matching similar to the syntax, but currently we either have to write proc or combine pin operator with `to_proc`, which is a bit verbose. ```ruby users in [*, ^(:admin?.to_proc), *] users in [*, -> (user) { user.admin? }, *] ``` Therefore, I propose introducing a new pattern into pattern matching. The pattern matches an object such that `pattern.to_proc === object`. This allows us to write code with a familiarity close to the syntax we're accustomed to. ```ruby users in [*, &:admin?, *] ``` -- https://bugs.ruby-lang.org/
Issue #21857 has been updated by matheusrich (Matheus Richard). Could you add why one would prefer writing `users in [*, &:admin?, *]` over `users.any?(&:admin?)`? ---------------------------------------- Feature #21857: Introduce to_proc pattern https://bugs.ruby-lang.org/issues/21857#change-116319 * Author: sanfrecce-osaka (Masatoshi Moritsuka) * Status: Open ---------------------------------------- When object has some logics, we can use `&object` syntax with Enumerable or Array, etc. ```ruby users.any?(&:admin?) ``` There are some times when I want to write pattern matching similar to the syntax, but currently we either have to write proc or combine pin operator with `to_proc`, which is a bit verbose. ```ruby users in [*, ^(:admin?.to_proc), *] users in [*, -> (user) { user.admin? }, *] ``` Therefore, I propose introducing a new pattern into pattern matching. The pattern matches an object such that `pattern.to_proc === object`. This allows us to write code with a familiarity close to the syntax we're accustomed to. ```ruby users in [*, &:admin?, *] ``` -- https://bugs.ruby-lang.org/
Issue #21857 has been updated by sanfrecce-osaka (Masatoshi Moritsuka).
Could you add why one would prefer writing `users in [*, &:admin?, *]` over `users.any?(&:admin?)`?
Pattern matching can be combined with As pattern to both check whether something matches and bind the matched value to a variable at the same time. `Array#any?` would suffice for just checking, but that's the key difference. In the description of this issue, I also had As pattern in mind as a motivation: ```ruby users in [*, &:admin? => admin_user, *] ``` You might wonder if `Array#find` would do the job, but there are cases where I want pattern matching to guarantee that a match will always be found: ```ruby # admin_user could be nil, and it's not clear that this code expects it to always be found admin_user = users.find(&:admin?) # If no match, NoMatchingPatternError is raised, making it clear that this code expects a match to always exist users => [*, &:admin? => admin_user, *] ``` Here's an example from code I wrote at work recently: ```ruby if statuses.intersection(available_statuses) in ^(:present?.to_proc) => target_statuses # any logics using target_statuses else # any logics end ``` Without pattern matching, assigning inside an if condition requires parentheses: ```ruby if (target_statuses = statuses.intersection(available_statuses)) && target_statuses.present? # any logics using target_statuses else # any logics end ``` ---------------------------------------- Feature #21857: Introduce to_proc pattern https://bugs.ruby-lang.org/issues/21857#change-116788 * Author: sanfrecce-osaka (Masatoshi Moritsuka) * Status: Assigned * Assignee: ktsj (Kazuki Tsujimoto) ---------------------------------------- When object has some logics, we can use `&object` syntax with Enumerable or Array, etc. ```ruby users.any?(&:admin?) ``` There are some times when I want to write pattern matching similar to the syntax, but currently we either have to write proc or combine pin operator with `to_proc`, which is a bit verbose. ```ruby users in [*, ^(:admin?.to_proc), *] users in [*, -> (user) { user.admin? }, *] ``` Therefore, I propose introducing a new pattern into pattern matching. The pattern matches an object such that `pattern.to_proc === object`. This allows us to write code with a familiarity close to the syntax we're accustomed to. ```ruby users in [*, &:admin?, *] ``` -- https://bugs.ruby-lang.org/
participants (2)
-
matheusrich (Matheus Richard) -
sanfrecce-osaka (Masatoshi Moritsuka)