Feature #16355
closedRaise NoMatchingPatternError when `expr in pat` doesn't match
Description
Currently, single line pattern matching(expr in pat
) returns true or false.
[1, 2, 3] in [x, y, z] #=> true (with assigning 1 to x, 2 to y, and 3 to z)
[1, 2, 3] in [1, 2, 4] #=> false
I think expr in pat
should raise an exception when it doesn't match.
Because if a user doesn't check the return value of expr in pat
, matching failure occurs implicitly and it may cause problems in subsequent processes.
expr in [0, x] # A user expects it always matches, but if it doesn't match...
...
(snip)
...
x.foo #=> NoMethodError (undefined method `foo' for nil:NilClass)
I also propose that expr in pat
returns the result of expr
if it matches.
It is similar to assignment.
x, y, z = 1, 2, 3 #=> [1, 2, 3]
[1, 2, 3] in [x, y, z] #=> [1, 2, 3]
Files
Updated by ktsj (Kazuki Tsujimoto) almost 5 years ago
- Related to Feature #15865: `<expr> in <pattern>` expression added
Updated by ktsj (Kazuki Tsujimoto) almost 5 years ago
- Description updated (diff)
Updated by palkan (Vladimir Dementyev) almost 5 years ago
Agree, that it could save users from unexpected behavior.
On the other hand, raising an exception drastically limits the application of online pattern matching: it won't be possible to use it with if ... else ...
or in select/filter
statements (here is a great example).
If users won't to ensure that a pattern matches, they can write (expr in ptrn) || raise "smth"
.
Having one-line patterns return true or false brings a lot of possibilities, IMO.
P.S. I was actually scanning the tracker for the mentions of the following situation I've just encountered:
assert_block do
{a:0, b: 1} in {a:, **nil}
a.nil? #=> this is not nil, which confused me at first; but now I think that this is a less evil than raising an exception
end
Updated by Eregon (Benoit Daloze) almost 5 years ago
I think this basically breaks [Feature #15865].
We should decide if expr in pattern
can be used as a condition (such as in if
) or not.
As @palkan (Vladimir Dementyev) said, it's already easy to use || raise NoMatchingPatternError
for assignment cases, but it's impossible (or very ugly) to use if expr in pattern
if we do the proposed change.
Updated by matz (Yukihiro Matsumoto) almost 5 years ago
I accept this proposal for two reasons:
- as OP described, returning boolean values from
in
pattern matching masks match failure. This can cause serious problems. - By this change, we cannot use
in
pattern matching inif
conditionals. But this style can be easily expressed bycase
pattern matching.
Matz.
Updated by nobu (Nobuyoshi Nakada) almost 5 years ago
- Status changed from Open to Closed
Applied in changeset git|8b4ee5d6ba92a385eedc9235ce0a2d5618deecf0.
Raise NoMatchingPatternError
when expr in
pat doesn't match
-
expr in pattern
should raiseNoMatchingError
when unmatched -
expr in pattern
should returnnil
. (this is unspecified, but
this feature is experimental, at all)
[Feature #16355]
Updated by ktsj (Kazuki Tsujimoto) almost 5 years ago
- Related to Feature #16370: Pattern matching with variable assignment (the priority of `in` operator) added
Updated by ktsj (Kazuki Tsujimoto) almost 4 years ago
- Related to Feature #17371: Reintroduce `expr in pat` added