From: Yukihiro Matsumoto Date: 2008-05-01T23:03:38+09:00 Subject: [ruby-dev:34563] Re: /(.)(.)/.match("ab").select {|v| true } is empty まつもと ゆきひろです In message "Re: [ruby-dev:34562] Re: /(.)(.)/.match("ab").select {|v| true } is empty" on Thu, 1 May 2008 21:54:15 +0900, Tanaka Akira writes: |> MatchData#selectはvalues_atのaliasですからEnumerable系の |> selectとは挙動が異なります。戻り値は指定した引数をインデック |> スとする値を要素とする配列です。RDocには以下のようにあります。 | |おぉ、rdoc は読んでませんでした。 | |しかし、その説明は 1.8.1 から 1.8.6 までの挙動とあっていません。 | |% ruby-1.8.6 -ve 'p(/(.)(.)(\d+)(\d)/.match("THX1138: The Movie").select(0, 2, -2))' |ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux] |-e:1:in `select': wrong number of arguments (3 for 0) (ArgumentError) | from -e:1 | |% ruby-1.8.6 -ve 'p(/(.)(.)(\d+)(\d)/.match("THX1138: The Movie").select { true })' |ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux] |["HX1138", "H", "X", "113", "8"] 1.8ではMatchData#selectは、ブロックが与えられたらEnumerable系、 引数が与えられたらvalues_atという動きをしていました。が、混じ るのは良くないだろうと思った覚えはあります。 で、MatchDataはEnumerableをincludeしていないし、selectだけ Enumerable系の動きをしてもしょうがないだろうと思って1.9を現 在のようにしたような気がしますが、1.8では分離する方向に進化 してたみたいですねぇ。同じ人が作業したとは思えない支離滅裂さ。 反省です。 |これをみると、むしろ rdoc による説明が間違っていて、その間違っ |た説明に 1.9 が従ってしまったと思えるのですがどうでしょうか? というか、1.8と1.9とで違う時点で異なる判断をしてしまったとい うことのようです。ごめんなさい。 |(そして、1.8.7 にそれが backport されて非互換性が発生してお |り、rubyspec で検出されるのですが。) 1.8の範囲内で重大な非互換性を発生させるのは本意ではないので、 いまさらですが1.8.7のMatchData#selectは1.8.6と同じように Enumerable系の動作に戻す(RDocもそれにあわせて書き換える)べき でしょう。 で、1.9でどうするかですが、MatchDataに対してEnumerable系の select(だけ)が必要になる局面はほとんどないと思いますし、とは いえselectというメソッドを見ると誰もがEnumerable系の動作を期 待しますから、いっそ削除してしまうのがよいのではないかと思い ます。 どうでしょう? まつもと ゆきひろ /:|)