Siena. です。

▼ [ruby-list:35265] < Take_tk さん

》 むしろ単純に Float#succ を self+1 で定義して 24時間単位の Time クラスを作って実験してみました。これがよさげ。

ちょっと気持ち悪さを感じます。なぜかを考えてみました。
# とかやっているうちに、既にいろいろと意見が出てますね

個人的には、n.succ() というと「n の *次に大きい* 数」と感じます。
つまり、n の属する集合は少なくとも全順序かつ離散的であって、
この全順序で与えられる順番で数え上げられると思っているようです。
この立場から考えると、連続な集合である (「次に大きい」という
概念が成立しない) 実数を表そうとしている Float に対して
#succ は定義できない/機能すべきではないのではないと思います。

実際に Float#succ は定義されていませんし、先立って #to_i
されているという事ですが、むしろ、#succ を直接呼んでしまって
NoMethodError を上げては、とか思ってしまいました。 # 過激 ^^;?

(Ruby 組み込みの) Time に対しても同様の違和感を感じます。
おまけに Time の場合には、差分が 0.01 秒か、1 日か、はたまた
1 世紀なのか、まるで見当が付かないという問題もありますね。

一方、今回の大元の Range はどういう「範囲」を表すものかというと、
Enumeratable なので全ての要素を数え上げられる集合ですよね。
連続な (不可算な) 数を表そうとしている Float を放り込んでいる
/放り込めてしまっているという点に違和感を感じます。
これも、(float..float) の時点で ArgumentError を(以下略 ^^;;)。

たけ(tk) さんの案は、どちらかというと連続集合中の区間を表す
Interval クラス (仮名) みたいなものが担うものではないでしょうか。
その上で、Interval#step( unit ) みたいなのを定義する、と。

Numeric 以外にも適用しやすくするために、仮に first が単位元を返す
#unit と、step 単位で n 個先の値を返す #advance を持つと仮定します。
First#unit は 1.0、Float#advance は self + n * unit ですね。
# String#unit は 1、String#advance は succ( n * unit ) かもしれない
まぁ、いろいろとやり過ぎとは思いますが ^^;

  def step( unit = first.unit() )  ## in class Interval
    n = 0
    while( ( val = first.advance( n, unit ) ) <= last )
      yield( val )
      n += 1
    end
  end
  alias :each :step  ## これは妥当かなぁ?

あと、(1..2) === 1.5 は ArgumentError となります (ruby 1.6.4) が、
Interval(仮) なら ( 1 <= 1.5 ) && ( 1.5 <= 2 ) という範囲の比較
として定義できるとか、開区間や半開区間も表せるようにできるとか、
それなりの意義はありそうに思います。

Interval(仮) のように連続な区間も表せるように Range を
拡張するというのもありえるとは思いますが、そうすると
少なくとも #to_a は妥当な定義が与えられないような気がします。

---
Siena. <mailto:siena / cr.chiba-u.ac.jp>