[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/
Issue #21857 has been updated by ktsj (Kazuki Tsujimoto). I understand the motivation, but I'm still not fully convinced that this particular use case is enough to justify introducing dedicated syntax. There are similar requests as well, such as wanting to match based on `respond_to?`. It might be more convincing if the proposal included a syntax that could cover those kinds of cases too. ---------------------------------------- Feature #21857: Introduce to_proc pattern https://bugs.ruby-lang.org/issues/21857#change-117356 * 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 (3)
-
ktsj (Kazuki Tsujimoto) -
matheusrich (Matheus Richard) -
sanfrecce-osaka (Masatoshi Moritsuka)