From: Yukihiro Matsumoto Date: 2014-04-20T22:58:33+09:00 Subject: [ruby-list:49797] Re: Range class? まつもと ゆきひろです Rangeの奇妙な振る舞いを理解するためには、Rangeのメソッドには、 Enumerableとして振る舞うものと、Intervalとして振る舞うものの の両方があることに注意しなければなりません。 Enumerableとして振る舞うものは離散的で、eachメソッドが生成す る要素を使います。Rangeの場合、eachは始点から1.0ずつ離れた値 が生成されます(数値の場合)。 Intervalとして振る舞うものは連続的で始点(begin)と終点(end)の 大きさで決まります。 たとえば、include?はeachを使い、cover?は始点と終点の間の比較 で判定します。 ですから、ご指摘のメソッドではこのような事情があります。 maxは終点を、minmaxは最終要素を返します。 sizeはeachの与える要素数を返します。 例として「0.5...5」は「0.5から1.0刻みで5.0を越えない要素の数」 という意味になり、それらの要素は[0.5, 1.5, 2.5, 3.5, 4.5]です から「(0.5...5).size」は5になります。 理解(or 納得)の一助になりましたでしょうか? まつもと ゆきひろ /:|) p.s. ただ、minmaxは[min,max]として定義したほうが良かったかもしれ ません。特に理由があって離散的にしてたわけではないような。 In message "Re: [ruby-list:49796] Range class?" on Sun, 20 Apr 2014 19:36:04 +0900 (JST), "Masa" writes: | |坂野正明です。 | |Range クラスの振舞いについて、二、三、不自然な点に |気付きました。 |いずれも滅多に遭遇するものではないでしょうが、 |意図された挙動では無いのではないかと思いました。 |マニュアルにも特に注意書きはありません。 |http://www.ruby-doc.org/core-2.1.1/Range.html |http://docs.ruby-lang.org/ja/2.1.0/class/Range.html | |以下のものです。 | |[1] max と minmax | |irb> (0...3.5).max |TypeError: cannot exclude non Integer end value | from (irb):1:in `max' |irb> (0...3.5).minmax # => [0, 3] | |この二つが異なる結果を返すのは、期待していませんでした。 |因みに、他の挙動(以下に例)は、納得できるものでした。 | |irb> (0...3).max # => 2 |irb> (0...3).minmax # => [0, 2] |irb> (0...3.5).max_by.each{|i|i} # => 3 |irb> (0...3.5).minmax_by.each{|i|i} # => [0, 3] | | |[2] size | |irb> (1..5.1).size # => 5 |irb> (1...5.1).size # => 5 |irb> (1..5).size # => 5 |irb> (1.2..5).size # => 4 |irb> (1...5).size # => 4 |irb> (1.0...5).size # => 4 |irb> (Rational(2,3)...5).size # => 4 |irb> (Rational(1,2)...5).size # => 4 |irb> (0.5...5).size # => 5 # Why not 4?? |irb> (Rational(1,3)...5).size # => 4 | |irb> (Rational(3,2)...5).size => 3 |irb> (1.5...5).size # => 4 # Why not 3?? |irb> (1.5...4.9).size # => 4 # Why not 3?? |irb> (1.5...Rational(49,10)).size # => 4 # Why not 3?? |irb> (1.5...Rational(45,10)).size # => 3 |irb> (1.5...4.5).size # => 3 | |Range の beginが Integerに一致しない Floatの時の |挙動が、他と矛盾します。 |端が Integer でないときの Numericの Rangeの size()とは |何ぞや、というのは議論(考え方)があってもいいと思いますが、 |同値(==)である Rationalとも返り値が異なることがあるのは |期待していませんでした。 | |また、最後の四例の endの Rational/Floatの例も |私の予想からは一部ずれていました。(beginはそうでは |ないけれど)endの値については、Numericの時に、 |四捨五入(但し、五は切捨て?)か何かをしているように見えます。 | | |以上です。 |なお、ここで使用した Ruby は以下です。 |% ruby2.1 --version |ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13] | |-- |坂野正明