/** section: Language * class ObjectRange * * Ranges represent an interval of values. The value type just needs to be * "compatible" — that is, to implement a `succ` method letting us step from * one value to the next (its successor). * * Prototype provides such a method for [[Number]] and [[String]], but you * are (of course) welcome to implement useful semantics in your own objects, * in order to enable ranges based on them. * * `ObjectRange` mixes in [[Enumerable]], which makes ranges very versatile. * It takes care, however, to override the default code for `include`, to * achieve better efficiency. * * While `ObjectRange` does provide a constructor, the preferred way to obtain * a range is to use the [[$R]] utility function, which is strictly equivalent * (only way more concise to use). **/ /** section: Language * $R(start, end[, exclusive = false]) -> ObjectRange * * Creates a new ObjectRange object. * This method is a convenience wrapper around the [[ObjectRange]] constructor, * but $R is the preferred alias. **/ function $R(start, end, exclusive) { return new ObjectRange(start, end, exclusive); } var ObjectRange = Class.create(Enumerable, (function() { /** * new ObjectRange(start, end[, exclusive = false]) * * Creates a new `ObjectRange`. * * The `exclusive` argument specifies whether `end` itself is a part of the * range. **/ function initialize(start, end, exclusive) { this.start = start; this.end = end; this.exclusive = exclusive; } function _each(iterator) { var value = this.start; while (this.include(value)) { iterator(value); value = value.succ(); } } /** * ObjectRange#include(value) -> Boolean * * Determines whether the value is included in the range. **/ function include(value) { if (value < this.start) return false; if (this.exclusive) return value < this.end; return value <= this.end; } return { initialize: initialize, _each: _each, include: include }; })());