Project

General

Profile

Feature #16355

Raise NoMatchingPatternError when `expr in pat` doesn't match

Added by ktsj (Kazuki Tsujimoto) 17 days ago. Updated 8 days ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:95889]

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

expr-in-pat-raises-error.patch (2.59 KB) expr-in-pat-raises-error.patch ktsj (Kazuki Tsujimoto), 11/20/2019 12:58 AM

Related issues

Related to Ruby master - Feature #15865: `<expr> in <pattern>` expressionClosedActions
Related to Ruby master - Feature #16370: Pattern matching with variable assignment (the priority of `in` operator)OpenActions

Associated revisions

Revision 8b4ee5d6
Added by nobu (Nobuyoshi Nakada) 8 days ago

Raise NoMatchingPatternError when expr in pat doesn't match

  • expr in pattern should raise NoMatchingError when unmatched
  • expr in pattern should return nil. (this is unspecified, but this feature is experimental, at all)

[Feature #16355]

Revision d1ef4fd0
Added by nobu (Nobuyoshi Nakada) 7 days ago

Make single line pattern matching void expression

Instead of returning nil, raise a syntax error if its value is
used. [Feature #16355]

History

#1

Updated by ktsj (Kazuki Tsujimoto) 17 days ago

#2

Updated by ktsj (Kazuki Tsujimoto) 17 days ago

  • Description updated (diff)

Updated by palkan (Vladimir Dementyev) 16 days 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) 12 days 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) 8 days 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 in if conditionals. But this style can be easily expressed by case pattern matching.

Matz.

#6

Updated by nobu (Nobuyoshi Nakada) 8 days 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 raise NoMatchingError when unmatched
  • expr in pattern should return nil. (this is unspecified, but this feature is experimental, at all)

[Feature #16355]

#7

Updated by ktsj (Kazuki Tsujimoto) 7 days ago

  • Related to Feature #16370: Pattern matching with variable assignment (the priority of `in` operator) added

Also available in: Atom PDF