From: "James M. Lawrence" Date: 2008-10-21T11:21:02+09:00 Subject: Re: prob with ranges Junkone wrote: > irb(main):025:0> (15..10).each do |n| > irb(main):026:1* print n > irb(main):027:1> end > => 15..10 I used this as a self-tutorial for learning RSpec for the first time. % spec ./specification -fs Synopsis - (3..7).to_a #=> [3, 4, 5, 6, 7] - (7..3).to_a #=> [] - reversible(3..7).to_a #=> [3, 4, 5, 6, 7] - reversible(7..3).to_a #=> [7, 6, 5, 4, 3] A forward-pointing Range (3..7) with r.exclude_end? == false - has invariant reversible(r) == r - has invariant reversible(r).object_id == r.object_id A backward-pointing Range (7..3) with r.exclude_end? == false - has invariant reversible(r) == ReverseRange.new(r.begin, r.end) A forward-pointing Range (3...7) with r.exclude_end? == true - is accepted by reversible() A backward-pointing Range (7...3) with r.exclude_end? == true - is rejected by reversible() ReverseRange instances are normally created with reversible() - reversible(7..3) #=> ReverseRange.new(7, 3) ReverseRange behaves similarly to Range - reversible(7..3).inspect #=> '#' - reversible(7..3).first #=> 7 - reversible(7..3).last #=> 3 - reversible(7..3).include?(9) #=> false - reversible(7..3).member?(4) #=> true - reversible(7..3).include?(4) #=> true - (7..3).include?(4) #=> false - has the same case/when semantics as Range ReverseRange can also be passed to reversible() - ReverseRange.new(3, 7).to_a #=> [] - reversible(ReverseRange.new(3, 7)).to_a #=> [3, 4, 5, 6, 7] - reversible(ReverseRange.new(3, 7)).is_a?(Range) #=> true - reversible(ReverseRange.new(7, 3)).is_a?(ReverseRange) #=> true ReverseRange#step(n) - argument n must be negative - reversible(7..3).to_enum(:step, -1).to_a #=> [7, 6, 5, 4, 3] - reversible(7..3).to_enum(:step, -2).to_a #=> [7, 5, 3] - reversible(7..3).to_enum(:step, -3).to_a #=> [7, 4] - reversible(7..3).to_enum(:step, -4).to_a #=> [7, 3] - reversible(7..3).to_enum(:step, -5).to_a #=> [7] - reversible(7..3).to_enum(:step, -99).to_a #=> [7] ReverseRange#step(n) with simple one-character String#pred - reversible('t'..'p').to_enum(:step, -1).to_a #=> %w[t s r q p] - reversible('t'..'p').to_enum(:step, -2).to_a #=> %w[t r p] - reversible('t'..'p').to_enum(:step, -3).to_a #=> %w[t q] - reversible('t'..'p').to_enum(:step, -4).to_a #=> %w[t p] - reversible('t'..'p').to_enum(:step, -5).to_a #=> %w[t] - reversible('t'..'p').to_enum(:step, -99).to_a #=> %w[t] ReverseRange details - has invariant r == r - has invariant r == ReverseRange.new(r.begin, r.end) - has invariant r.eql?(r) == true - has invariant r.eql?(ReverseRange.new(r.begin, r.end)) == true - has invariant r.exclude_end? == false - has invariant r.inspect == r.to_s - calls #pred on elements - leaves #pred definition to the user reversible() - accepts Range object - accepts Range-quacking object - fails if argument does not quack like Range Finished in 0.029019 seconds 46 examples, 0 failures http://github.com/quix/reverse_range/tree/master Past-endpoint ranges (7...3) seemed too ambiguous, so I just disallowed it. In particular if (3...5).to_a == [3, 4], then reversible(5...3).to_a == [4, 3]. Do not want. I considered using the name 'magnetic' instead of 'reversible', as it has the effect of flipping around to find the right polarity. James M. Lawrence -- Posted via http://www.ruby-forum.com/.