75 lines
2.1 KiB
JavaScript
75 lines
2.1 KiB
JavaScript
/** 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
|
|
};
|
|
})());
|
|
|