iyi

Prelude, 0.18.0

Range

Ranges — SPEC.md, "0.1.0", item 3.

In the prelude: every iyi program has it, with no import.

The compiler expands a range literal to Range.new(from, to, exclusive) (literal_expander.cr) and predefines the type to refer to it; with no methods, (1..10).each was refused with "wrong number of arguments for 'Range(B, E).new'", a constructor nobody wrote. A range here counts up by one and stops: no Enumerable, no step, no reverse iteration.

Range(B, E)struct

Rangeiyi doc Range
struct Range(B, E)

  # A range is a value, so two written the same way are the same range:
  # `Object#==` is identity, and `(1..3) == (1..3)` was false. `1..3` and
  # `1...3` differ, and that is the flag's whole job.
  def ==(other : self) : Bool

  # `when 1..5` is `(1..5) === x`: inclusion. `==` answered, and no arm matched.
  def ===(value) : Bool

  def begin : B

  # The inclusive walk stops *at* the end rather than stepping past it: with
  # `value <= @end` the last step left the type on the checked `+`, so
  # `(2147483645..2147483647).each` panicked with "arithmetic overflow" at
  # the value it was asked to yield last.
  def each(& : (B -> Nil)) : Nil

  def end : E

  # `1...10` excludes its end, `1..10` includes it.
  def exclusive? : Bool

  # And hashing follows equality, or equal ranges would land in two slots.
  def hash : Int32

  # The three a range is written for: a value per position, the positions
  # that answer, and the total.
  def map(& : (B -> U)) : Array(U) forall U

  def new(begin __arg0 : B, end __arg1 : E, exclusive : Bool)

  def select(& : (B -> Bool)) : Array(B)

  def size : Int32

  def sum : B

  def to_a : Array(B)

  # `1..5` and `1...3`, each end inspected and a nil one left out, as the
  # other library writes one; `Object#to_s` printed `Range(Int32, Int32)`.
  def to_s : String
end