Issue #14916 has been updated by timriley (Tim Riley).


Like I just mentioned in https://bugs.ruby-lang.org/issues/14869#note-13, would you consider changing this to run the explicit `#to_a` converter as well as (or instead of) the implicit `#to_ary`? This would make the matching even more flexible, since it could be using with objects that want to provide an interface for conversion into an array without necessarily pretending to "be" one (as is the case for `#to_ary`).

----------------------------------------
Feature #14916: Proposal to add Array#===
https://bugs.ruby-lang.org/issues/14916#change-73392

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## 概要

`Array#===` を追加する提案になります。
基本的な動作は『`Array#==` の `===` で比較する版』になります。


## 仕様

配列の各要素をそれぞれ順に `===` で比較し、全要素が `true` の場合に `true` を返す。そうでない場合は `false` を返す。


### 動作例

```ruby
# 配列の各要素を #=== を使用して比較する
[ String, /\w/ ]          === [ "a", "c", 7 ]   # => false
[ String, /\w/, (1..10) ] === [ "a", "c", 7 ]   # => true
[ String, /\w/, (1..10) ] === [ "a", "!", 42 ]  # => false
```


### 真を返すケース

* レシーバと引数が配列で同じサイズかつ、各要素を `===` で比較したときに全て `true` になる場合
* レシーバと引数が同じオブジェクトの場合


### 偽を返すケース

* レシーバと引数が配列で同じサイズかつ、各要素を `===` で比較したときに `false` がある場合
* レシーバと引数の配列のサイズが異なる場合
* 引数が配列以外の場合


## ユースケース


### 引数の値によって処理を変える

可変長引数で引数を受け取り、そのまま case-when で値を精査する

```ruby
def plus *args
  case args
  # 数値の場合
  when [Integer, Integer]
    args[0] + args[1]
  # 数字の場合
  when [/^\d+$/, /^\d+$/]
    args[0].to_i + args[1].to_i
  # それ以外はエラー
  else
    raise "Error"
  end
end

p plus 1, 2
# => 3
p plus "3", "4"
# => 7
p plus "homu", "mado"
# Error (RuntimeError)
```


### FizzBuzz を用いた例

任意の処理の結果を複数回参照したい場合、配列でまとめて case-when で利用する

```ruby
def fizzbuzz n
  _ = proc { true }
  case [n % 3, n % 5]
  # n % 3 === 0 && n % 5 === 0
  when [0, 0]
    "FizzBuzz"
  # n % 3 === 0
  when [0, _]
    "Fizz"
  # n % 5 === 0
  when [_, 0]
    "Buzz"
  else
    n
  end
end

p (1..20).map &method(:fizzbuzz)
# => [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, 17, "Fizz", 19, "Buzz"]
```

## 関連しそうなチケット

* [Feature #14869: Proposal to add Hash#=== - Ruby trunk - Ruby Issue Tracking System](https://bugs.ruby-lang.org/issues/14869?next_issue_id=14866&prev_issue_id=14870)
* [Feature #14913: Extend case to match several values at once - Ruby trunk - Ruby Issue Tracking System](https://bugs.ruby-lang.org/issues/14913)


以上、 `Array#===` に関する提案になります。
挙動に関して疑問点や意見などございましたらコメント頂けると助かります。



---Files--------------------------------
array_eqq.patch (3.06 KB)
array_eqq.patch (3.2 KB)
array_eqq.patch (3.41 KB)


-- 
https://bugs.ruby-lang.org/