diff options
Diffstat (limited to 'utils/lib/util.js')
-rwxr-xr-x | utils/lib/util.js | 108 |
1 files changed, 60 insertions, 48 deletions
diff --git a/utils/lib/util.js b/utils/lib/util.js index 04865d8..510e322 100755 --- a/utils/lib/util.js +++ b/utils/lib/util.js @@ -13,6 +13,14 @@ exports.operator = function (name, length, block) { var operator = function () { var args = exports.array(arguments); var completion = function (object) { + if ( + typeof object == "object" && + object !== null && // seriously? typeof null == "object" + name in object && // would throw if object === null + // not interested in literal objects: + !Object.prototype.hasOwnProperty.call(object, name) + ) + return object[name].apply(object, args); return block.apply( this, [object].concat(args) @@ -26,6 +34,7 @@ exports.operator = function (name, length, block) { return completion.call(this, args.shift()); } }; + operator.name = name; operator.displayName = name; operator.length = length; operator.operator = block; @@ -54,7 +63,7 @@ exports.object = exports.operator('object', 1, function (object) { exports.object.copy = function (object) { var copy = {}; - Object.keys(object).forEach(function (key) { + exports.object.keys(object).forEach(function (key) { copy[key] = object[key]; }); return copy; @@ -62,7 +71,7 @@ exports.object.copy = function (object) { exports.object.deepCopy = function (object) { var copy = {}; - Object.keys(object).forEach(function (key) { + exports.object.keys(object).forEach(function (key) { copy[key] = exports.deepCopy(object[key]); }); return copy; @@ -72,28 +81,35 @@ exports.object.eq = function (a, b, stack) { return ( !exports.no(a) && !exports.no(b) && exports.array.eq( - Object.keys(a), - Object.keys(b) + exports.sort(exports.object.keys(a)), + exports.sort(exports.object.keys(b)) ) && - Object.keys(a).every(function (key) { + exports.object.keys(a).every(function (key) { return exports.eq(a[key], b[key], stack); }) ); }; exports.object.len = function (object) { - return Object.keys(object).length; + return exports.object.keys(object).length; }; exports.object.has = function (object, key) { return Object.prototype.hasOwnProperty.call(object, key); }; -exports.object.keys = Object.keys; +exports.object.keys = function (object) { + var keys = []; + for (var key in object) { + if (exports.object.has(object, key)) + keys.push(key); + } + return keys; +}; exports.object.values = function (object) { var values = []; - Object.keys(object).forEach(function (key) { + exports.object.keys(object).forEach(function (key) { values.push(object[key]); }); return values; @@ -101,7 +117,7 @@ exports.object.values = function (object) { exports.object.items = function (object) { var items = []; - Object.keys(object).forEach(function (key) { + exports.object.keys(object).forEach(function (key) { items.push([key, object[key]]); }); return items; @@ -128,7 +144,7 @@ exports.object.complete = function (target, source) { exports.object.repr = function (object) { return "{" + - Object.keys(object) + exports.object.keys(object) .map(function (key) { return exports.enquote(key) + ": " + exports.repr(object[key]); @@ -139,6 +155,8 @@ exports.object.repr = function (object) { // array exports.array = function (array) { + if (!exports.isArrayLike(array)) + return exports.items(array); return Array.prototype.slice.call(array); }; @@ -147,7 +165,7 @@ exports.isArrayLike = function(object) { typeof object === "object" && ( object.constructor === Array || - object.callee + typeof object.callee !== "undefined" ); }; @@ -166,19 +184,12 @@ exports.array.has = function (array, value) { }; exports.array.put = function (array, key, value) { - array.splice.apply( - array, - [ - key, - 1 - ].concat([value]) - .concat(array.slice(key, array.length)) - ); + array.splice(key, 0, value); return array; }; -exports.array.del = function (array, key, value) { - array.splice(key, 1); +exports.array.del = function (array, begin, end) { + array.splice(begin, end === undefined ? 1 : (end - begin)); return array; }; @@ -191,7 +202,7 @@ exports.array.eq = function (a, b, stack) { }; exports.array.lt = function (a, b) { - var length = Math.max(a, b); + var length = Math.max(a.length, b.length); for (var i = 0; i < length; i++) if (!exports.eq(a[i], b[i])) return exports.lt(a[i], b[i]); @@ -206,7 +217,7 @@ exports.apply = exports.operator('apply', 2, function (args, block) { return block.apply(this, args); }); -exports.copy = function (object) { +exports.copy = exports.operator('copy', 1, function (object) { if (exports.no(object)) return object; if (exports.isArrayLike(object)) @@ -214,9 +225,9 @@ exports.copy = function (object) { if (typeof object == 'object') return exports.object.copy(object); return object; -}; +}); -exports.deepCopy = function (object) { +exports.deepCopy = exports.operator('deepCopy', 1, function (object) { if (exports.no(object)) return object; if (exports.isArrayLike(object)) @@ -224,9 +235,9 @@ exports.deepCopy = function (object) { if (typeof object == 'object') return exports.object.deepCopy(object); return object; -}; +}); -exports.repr = function (object) { +exports.repr = exports.operator('repr', 1, function (object) { if (exports.no(object)) return String(object); if (exports.isArrayLike(object)) @@ -236,31 +247,31 @@ exports.repr = function (object) { if (typeof object == 'string') return exports.enquote(object); return object.toString(); -}; +}); -exports.keys = function (object) { +exports.keys = exports.operator('keys', 1, function (object) { if (exports.isArrayLike(object)) return exports.range(object.length); else if (typeof object == 'object') - return Object.keys(object); + return exports.object.keys(object); return []; -}; +}); -exports.values = function (object) { +exports.values = exports.operator('values', 1, function (object) { if (exports.isArrayLike(object)) return exports.array(object); else if (typeof object == 'object') return exports.object.values(object); return []; -}; +}); -exports.items = function (object) { +exports.items = exports.operator('items', 1, function (object) { if (exports.isArrayLike(object) || typeof object == "string") return exports.enumerate(object); else if (typeof object == 'object') return exports.object.items(object); return []; -}; +}); exports.len = exports.operator('len', 1, function (object) { if (exports.isArrayLike(object)) @@ -312,7 +323,7 @@ exports.getset = exports.operator('getset', 3, function (object, key, value) { exports.del = exports.operator('del', 2, function (object, begin, end) { if (exports.isArrayLike(object)) - exports.array.del(object, begin, end); + return exports.array.del(object, begin, end); delete object[begin]; return object; }); @@ -434,9 +445,9 @@ exports.enumerate = function (array, start) { // arithmetic, transitive, and logical operators -exports.is = exports.operator('is', 2, function (a, b) { +exports.is = function (a, b) { return a === b; -}); +}; exports.eq = exports.operator('eq', 2, function (a, b, stack) { if (!stack) @@ -550,16 +561,17 @@ exports.sort = function (array, compare) { compare = exports.compare; if (compare.by) { /* schwartzian transform */ - array.splice( - 0, - array.length, - array.map(function (value) { - return [compare.by(value), value]; - }).sort(function (a, b) { - return exports.compare(a[0], b[0]); - }).map(function (pair) { - return pair[1]; - }) + array.splice.apply( + array, + [0, array.length].concat( + array.map(function (value) { + return [compare.by(value), value]; + }).sort(function (a, b) { + return exports.compare(a[0], b[0]); + }).map(function (pair) { + return pair[1]; + }) + ) ); } else { array.sort(compare); |