背景
事の発端
-
Kinx では Ruby と同じように文字列の Range をサポートしたが、"z" の次は "aa" なので、単純に辞書順ではない
<=>
演算子を定義してました。 - で、普通にソートすると、当然辞書順にはなりません。(文字列長いほうが大きいと判断されるため)
- で、そういえば Ruby は辞書順ですね、文字列のソート。なんか変だな。
[注] Kinx って何?
最初の動機 ⇒ こちらをご覧ください
リポジトリ ⇒ こちらをご覧ください
確認してみた
-
irb で
"b" <=> "aa"
やってみよう、irb(main):001:0> "b" <=> "aa" => 1 irb(main):002:0>
-
おゃ?!
-
では Range では?試しに
"a".."c"
を表示すると。irb(main):002:0> a = "a".."c" => "a".."c" irb(main):003:0> a.each {|e| p e } "a" "b" "c" => "a".."c"
-
ちゃんと列挙されます。では疑惑の
"b".."aa"
は?irb(main):004:0> a = "b".."aa" => "b".."aa" irb(main):005:0> a.each {|e| p e } => "b".."aa"
-
なんと、
"b".."aa"
は使えないのか...
結論
私の気持ち
やっぱり "b".."aa"
も 動いてほしい よね。"b"
の次は "c"
で、そのまま "z"
まで進んだ後に "aa"
で終了してほしいなーと思いましたが、他の方はどうなんでしょう。
実際に行ったこと
なので、最新のリポジトリ(0.8.1 には入ってません)では以下のように修正しましたよ。
- 文字列の
<=>
演算子は辞書順に戻した。 -
class Range
の<=>
の部分は文字列だけ特別扱いにして"b".."aa"
も使えるようにした。-
"b", "c", "d", ..., "z", "aa"
になる。
-
おわりに
ということで、ここ(=文字に対する Range の仕様)は Ruby と仕様が違います。何か問題があればお知らせください。
まあ、こんな特殊な条件ではあまり使わないので、誰も困ってなさそうですが。だから別にどっちでもいいと言えばどっちでもいいかもしれません。細かい話でした。
Ruby 的にはどうなんでしょうね。想定内なのか、想定外なのか。意図してなのか、そうでないのか。まあ定義が明確で、定義に従った動作なので、こういうもの=仕様、ってことで落ち着きそうですが。
ではまた、次回。