[ruby-list:49797] Re: Range class?
From:
Yukihiro Matsumoto <matz@...>
Date:
2014-04-20 13:58:33 UTC
List:
ruby-list #49797
まつもと ゆきひろです
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" <imagine@sakano.co.uk> 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]
|
|--
|坂野正明