Skip to content
Permalink
Browse files

Merge pull request #663 from topazproject/tim/Range#step

copy Range#step from Rubinius
  • Loading branch information
alex committed Apr 27, 2013
2 parents 02956f5 + bfd9d0b commit 5747acb2b7b03f93126de8cd34cee78b11e547d2
Showing with 57 additions and 42 deletions.
  1. +57 −0 lib-topaz/range.rb
  2. +0 −42 spec/tags/core/range/step_tags.txt
@@ -29,6 +29,63 @@ def each(&block)
self
end

def step(step_size = 1, &block)
return self.to_enum(:step, step_size) unless block
first = self.begin
last = self.end

if step_size.kind_of? Float or first.kind_of? Float or last.kind_of? Float
# if any are floats they all must be
begin
step_size = Float(from = step_size)
first = Float(from = first)
last = Float(from = last)
rescue ArgumentError
raise TypeError, "no implicit conversion to float from #{from.class}"
end
else
step_size = Topaz.convert_type(step_size, Integer, :to_int)
end

if step_size <= 0
raise ArgumentError, "step can't be negative" if step_size < 0
raise ArgumentError, "step can't be 0"
end

if first.kind_of?(Float)
err = (first.abs + last.abs + (last - first).abs) / step_size.abs * Float::EPSILON
err = 0.5 if err > 0.5
if self.exclude_end?
n = ((last - first) / step_size - err).floor
n += 1 if n * step_size + first < last
else
n = ((last - first) / step_size + err).floor + 1
end

i = 0
while i < n
d = i * step_size + first
d = last if last < d
yield d
i += 1
end
elsif first.kind_of?(Numeric)
d = first
while self.exclude_end? ? d < last : d <= last
yield d
d += step_size
end
else
counter = 0
each do |o|
yield o if counter % step_size == 0
counter += 1
end
end

return self
end

def first(*args)
if args.empty?
self.begin
@@ -1,44 +1,2 @@
fails:Range#step returns an enumerator when no block is given
fails:Range#step returns self
fails:Range#step raises TypeError if step
fails:Range#step calls #to_int to coerce step to an Integer
fails:Range#step raises a TypeError if step does not respond to #to_int
fails:Range#step raises a TypeError if #to_int does not return an Integer
fails:Range#step coerces the argument to integer by invoking to_int
fails:Range#step raises a TypeError if the first element does not respond to #succ
fails:Range#step raises an ArgumentError if step is 0
fails:Range#step raises an ArgumentError if step is 0.0
fails:Range#step raises an ArgumentError if step is negative
fails:Range#step with inclusive end and Integer values yields Integer values incremented by 1 and less than or equal to end when not passed a step
fails:Range#step with inclusive end and Integer values yields Integer values incremented by an Integer step
fails:Range#step with inclusive end and Integer values yields Float values incremented by a Float step
fails:Range#step with inclusive end and Float values yields Float values incremented by 1 and less than or equal to end when not passed a step
fails:Range#step with inclusive end and Float values yields Float values incremented by an Integer step
fails:Range#step with inclusive end and Float values yields Float values incremented by a Float step
fails:Range#step with inclusive end and Float values returns Float values of 'step * n + begin <= end'
fails:Range#step with inclusive end and Integer, Float values yields Float values incremented by 1 and less than or equal to end when not passed a step
fails:Range#step with inclusive end and Integer, Float values yields Float values incremented by an Integer step
fails:Range#step with inclusive end and Integer, Float values yields Float values incremented by a Float step
fails:Range#step with inclusive end and Float, Integer values yields Float values incremented by 1 and less than or equal to end when not passed a step
fails:Range#step with inclusive end and Float, Integer values yields Float values incremented by an Integer step
fails:Range#step with inclusive end and Float, Integer values yields Float values incremented by a Float step
fails:Range#step with inclusive end and String values yields String values incremented by #succ and less than or equal to end when not passed a step
fails:Range#step with inclusive end and String values yields String values incremented by #succ called Integer step times
fails:Range#step with inclusive end and String values raises a TypeError when passed a Float step
fails:Range#step with inclusive end and String values calls #succ on begin and each element returned by #succ
fails:Range#step with exclusive end and Integer values yields Integer values incremented by 1 and less than end when not passed a step
fails:Range#step with exclusive end and Integer values yields Integer values incremented by an Integer step
fails:Range#step with exclusive end and Integer values yields Float values incremented by a Float step
fails:Range#step with exclusive end and Float values yields Float values incremented by 1 and less than end when not passed a step
fails:Range#step with exclusive end and Float values yields Float values incremented by an Integer step
fails:Range#step with exclusive end and Float values yields Float values incremented by a Float step
fails:Range#step with exclusive end and Float values returns Float values of 'step * n + begin < end'
fails:Range#step with exclusive end and Integer, Float values yields Float values incremented by 1 and less than end when not passed a step
fails:Range#step with exclusive end and Integer, Float values yields Float values incremented by an Integer step
fails:Range#step with exclusive end and Integer, Float values yields an Float and then Float values incremented by a Float step
fails:Range#step with exclusive end and Float, Integer values yields Float values incremented by 1 and less than end when not passed a step
fails:Range#step with exclusive end and Float, Integer values yields Float values incremented by an Integer step
fails:Range#step with exclusive end and Float, Integer values yields Float values incremented by a Float step
fails:Range#step with exclusive end and String values yields String values incremented by #succ and less than or equal to end when not passed a step
fails:Range#step with exclusive end and String values yields String values incremented by #succ called Integer step times
fails:Range#step with exclusive end and String values raises a TypeError when passed a Float step

0 comments on commit 5747acb

Please sign in to comment.
You can’t perform that action at this time.