Levin Alexander wrote: > Robert Klemme <bob.news / gmx.net> wrote: > >>> Interesting. I would lean towards (b) (which I believe is the >>> current implementation if exclude_end? is false). >> >> In that case the inclusion of Enumerable becomes questionable. > > But Ranges have many other uses which depend on it being Enumerable Yeah, certainly. >>> (a) is not really practical because Range is not always Enumerable >>> and this also conflicts with my mental model of a "Range" >> >> Right: >> >>>> (1.5 .. 3.4).to_a >> TypeError: cannot iterate from Float >> from (irb):14:in `each' >> from (irb):14:in `to_a' >> from (irb):14 >> >> We have the weired situation that a Range where left and right are >> enumerable (integers, strings) the inclusion of Enumerable is ok and >> for > > A range is only Enumerable if the left side defines +succ+ > > >> (0..Math::PI).to_a > => [0, 1, 2, 3] > >> class Float; def succ; self+0.8; end; end; > => nil > >> (0.1..2.0).to_a > => [0.1, 0.9, 1.7] > >> non enumerable types (Float) it's not. That's a bit weired situation >> IMHO, at least not exactly good design. > > I don't believe that it is much of a problem in practice. Yeah, probably. Since generally Ruby favours pragmatic solutions over formally more correct solutions we probably should leave it as is. In fact, I haven't tripped into that trap yet. :-) > Maybe Range should have a method enumerable? so that you can check if > each is going to work before you actually use it. > > class Range > def enumerable? > first.respond_to?(:succ) > end > end > > r = (1..10) > arr = r.enumerable? ? r.entries : [] Yeah, probably. Though I would not dare to guess how often this is really needed... Kind regards robert