From 1db649bd616ea281b50d59ebebd0a6b0036d2550 Mon Sep 17 00:00:00 2001 From: rolux Date: Sat, 7 Jan 2012 12:50:02 +0530 Subject: [PATCH] add Function.js, some updates in OxJS --- source/Ox/js/Array.js | 35 ++++++++++++++++ source/Ox/js/Collection.js | 85 ++------------------------------------ source/Ox/js/Core.js | 45 ++++++++++++++++++-- source/Ox/js/Fallback.js | 8 ++-- source/Ox/js/Function.js | 29 +++++++++++++ source/Ox/js/Object.js | 11 +++++ 6 files changed, 123 insertions(+), 90 deletions(-) create mode 100644 source/Ox/js/Function.js diff --git a/source/Ox/js/Array.js b/source/Ox/js/Array.js index bcad2fcd..dc6871c6 100644 --- a/source/Ox/js/Array.js +++ b/source/Ox/js/Array.js @@ -48,6 +48,41 @@ Ox.merge = function(arr) { return arr; }; +/*@ +Ox.range Python-style range + (stop) -> <[n]> range + Returns an array of integers from 0 (inclusive) to + stop (exclusive). + (start, stop) -> <[n]> range + Returns an array of integers from start (inclusive) to + stop (exclusive). + (start, stop, step) -> <[n]> range + Returns an array of numbers from start (inclusive) to + stop (exclusive), incrementing by step. + start Start value + stop Stop value + step Step value + > Ox.range(3) + [0, 1, 2] + > Ox.range(1, 4) + [1, 2, 3] + > Ox.range(3, 0) + [3, 2, 1] + > Ox.range(1, 2, 0.5) + [1, 1.5] + > Ox.range(-1, -2, -0.5) + [-1, -1.5] +@*/ +Ox.range = function() { + var args = Ox.makeArray(arguments), + arr = []; + args.push(function(i) { + arr.push(i); + }); + Ox.loop.apply(null, args); + return arr; +}; + /*@ Ox.sort Sorts an array, handling leading digits and ignoring capitalization arr Array diff --git a/source/Ox/js/Collection.js b/source/Ox/js/Collection.js index a4e0b6fa..f69c6283 100644 --- a/source/Ox/js/Collection.js +++ b/source/Ox/js/Collection.js @@ -11,7 +11,6 @@ Ox.avg Returns the average of an array's values, or an object's properties > Ox.avg('avg is 0.1') 0.1 @*/ - Ox.avg = function(obj) { return Ox.sum(obj) / Ox.len(obj); }; @@ -44,9 +43,8 @@ Ox.copy Returns a (shallow or deep) copy of an object or array > Ox.clone(0) 0 @*/ - Ox.copy = Ox.clone = function(col, deep) { - // fixme: remove references to Ox.clone + // fixme: copy or clone? // fixme: is there any use case for shallow copy? var ret = Ox.isArray(col) ? [] : {}; if (deep) { @@ -109,7 +107,6 @@ Ox.filter Filters a collection by a given condition > Ox.filter(' foo bar ', function(v) { return v != ' '; }) 'foobar' @*/ - Ox.filter = function(col, fn) { var type = Ox.typeOf(col), ret = type == 'array' ? [] : type == 'object' ? {} : ''; @@ -285,7 +282,6 @@ Ox.getset Generic getter and setter function > Ox.test.object.options({foo: "foo", bar: "bar"}).options() {"key": "val", "foo": "foo", "bar": "bar"} @*/ - Ox.getset = function(obj, args, callback, context) { var obj_ = Ox.clone(obj), ret; if (args.length == 0) { @@ -322,6 +318,8 @@ Ox.isEmpty Returns true if a collection is empty false > Ox.isEmpty(null) false + > Ox.isEmpty(0) + false > Ox.isEmpty() false @*/ @@ -345,7 +343,6 @@ Ox.keys Returns the keys of a collection > Ox.keys('abc') [0, 1, 2] @*/ - // fixme: is this really needed? arrays... ok... but strings?? Ox.keys = function(obj) { var keys = []; @@ -402,47 +399,6 @@ Ox.len = function(col) { : type == 'object' ? Ox.values(col).length : void 0; }; -/*@ -Ox.loop For-loop, functional-style - Returning false from the iterator function acts like a - break statement. Unlike a for loop, - Ox.loop doesn't leak its counter variable to the outer scope, - but returns it. - (stop, callback) -> Next value - equivalent to for (var i = 0; i < stop; i++) - (start, stop, callback) -> Next value - equivalent to for (var i = start; i < stop; i++) or, - if start is larger than stop, - for (var i = start; i > stop; i--) - (start, stop, step, callback) -> Next value - equivalent to for (var i = start; i < stop; i += step) or, - if step is negative, - for (var i = start; i > stop; i += step) - start Start value - stop Stop value (exclusive) - step Step value - callback Iterator function - i Counter value - > Ox.loop(10, function(i) { return i != 4; }) - 4 - > Ox.loop(0, 3, 2, function() {}) - 4 -@*/ -Ox.loop = function() { - var len = arguments.length, - start = len > 2 ? arguments[0] : 0, - stop = arguments[len > 2 ? 1 : 0], - step = len == 4 ? arguments[2] : (start <= stop ? 1 : -1), - callback = arguments[len - 1], - i; - for (i = start; step > 0 ? i < stop : i > stop; i += step) { - if (callback(i) === false) { - break; - }; - } - return i; -}; - /*@ Ox.makeArray Takes an array-like object and returns a true array Alias for Array.prototype.slice.call @@ -558,41 +514,6 @@ Ox.min = function(col) { return Math.min.apply(Math, Ox.values(col)); }; -/*@ -Ox.range Python-style range - (stop) -> <[n]> range - Returns an array of integers from 0 (inclusive) to - stop (exclusive). - (start, stop) -> <[n]> range - Returns an array of integers from start (inclusive) to - stop (exclusive). - (start, stop, step) -> <[n]> range - Returns an array of numbers from start (inclusive) to - stop (exclusive), incrementing by step. - start Start value - stop Stop value - step Step value - > Ox.range(3) - [0, 1, 2] - > Ox.range(1, 4) - [1, 2, 3] - > Ox.range(3, 0) - [3, 2, 1] - > Ox.range(1, 2, 0.5) - [1, 1.5] - > Ox.range(-1, -2, -0.5) - [-1, -1.5] -@*/ -Ox.range = function() { - var args = Ox.makeArray(arguments), - arr = []; - args.push(function(i) { - arr.push(i); - }); - Ox.loop.apply(null, args); - return arr; -}; - /*@ Ox.setPropertyOnce Sets a property once Given a array of objects, each of which has a property with a boolean diff --git a/source/Ox/js/Core.js b/source/Ox/js/Core.js index 3c06c929..5e12f313 100644 --- a/source/Ox/js/Core.js +++ b/source/Ox/js/Core.js @@ -70,8 +70,6 @@ Some conventions: : expression; */ -// FIXME: add memoize - // todo: check http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ // also see https://github.com/tlrobinson/narwhal/blob/master/lib/util.js @@ -81,7 +79,6 @@ Ox The Ox object (value) -> wrapped value value <*> Any value @*/ - window.Ox = function(val) { return Ox.wrap(val); }; @@ -103,7 +100,6 @@ Ox.load Loads a module callback Callback function success If true, the module has been loaded successfully @*/ - Ox.load = function() { var callback = arguments[arguments.length - 1], counter = 0, @@ -224,6 +220,47 @@ Ox.Log = (function() { return that; }()); +/*@ +Ox.loop For-loop, functional-style + Returning false from the iterator function acts like a + break statement. Unlike a for loop, + Ox.loop doesn't leak its counter variable to the outer scope, + but returns it. + (stop, callback) -> Next value + equivalent to for (var i = 0; i < stop; i++) + (start, stop, callback) -> Next value + equivalent to for (var i = start; i < stop; i++) or, + if start is larger than stop, + for (var i = start; i > stop; i--) + (start, stop, step, callback) -> Next value + equivalent to for (var i = start; i < stop; i += step) or, + if step is negative, + for (var i = start; i > stop; i += step) + start Start value + stop Stop value (exclusive) + step Step value + callback Iterator function + i Counter value + > Ox.loop(10, function(i) { return i != 4; }) + 4 + > Ox.loop(0, 3, 2, function() {}) + 4 +@*/ +Ox.loop = function() { + var len = arguments.length, + start = len > 2 ? arguments[0] : 0, + stop = arguments[len > 2 ? 1 : 0], + step = len == 4 ? arguments[2] : (start <= stop ? 1 : -1), + callback = arguments[len - 1], + i; + for (i = start; step > 0 ? i < stop : i > stop; i += step) { + if (callback(i) === false) { + break; + }; + } + return i; +}; + /*@ Ox.print Prints its arguments to the console (arg, ...) -> String diff --git a/source/Ox/js/Fallback.js b/source/Ox/js/Fallback.js index e21cb7b1..2ab2e492 100644 --- a/source/Ox/js/Fallback.js +++ b/source/Ox/js/Fallback.js @@ -35,7 +35,7 @@ if (!Array.prototype.forEach) { fn.call(that, arr[i], i, arr); } } - } + }; } // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf @@ -55,7 +55,7 @@ if (!Array.prototype.indexOf) { } } return ret; - } + }; } // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map @@ -74,7 +74,7 @@ if (!Array.prototype.map) { } } return ret; - } + }; } // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce @@ -116,5 +116,5 @@ if (!Object.keys) { } } return ret; - } + }; } diff --git a/source/Ox/js/Function.js b/source/Ox/js/Function.js new file mode 100644 index 00000000..c3958401 --- /dev/null +++ b/source/Ox/js/Function.js @@ -0,0 +1,29 @@ +/*@ +Ox.cache Memoize a function + + > f(10) == f(10); + true + > f(10) == f.clear()(10); + false +@*/ +Ox.cache = function(fn) { + var cache = {}, + ret = function() { + var key = JSON.stringify(Ox.makeArray(arguments)); + return key in cache ? cache[key] + : (cache[key] = fn.apply(this, arguments)); + }; + ret.clear = function() { + if (arguments.length == 0) { + cache = {}; + } else { + Ox.toArray(arguments).forEach(function(key) { + delete cache[key]; + }); + } + return ret; + } + return ret; +}; \ No newline at end of file diff --git a/source/Ox/js/Object.js b/source/Ox/js/Object.js index c83b6ce7..3a021489 100644 --- a/source/Ox/js/Object.js +++ b/source/Ox/js/Object.js @@ -31,6 +31,17 @@ Ox.keyOf = function(obj, val) { return key; }; +/*@ +Ox.methods Returns a sorted list of all method names of an object + > Ox.methods({a: [], b: false, f: function() {}, n: 0, o: {}, s: ''}) + ['f'] +@*/ +Ox.methods = function(obj) { + return Object.keys(obj).filter(function(key) { + return Ox.isFunction(obj[key]); + }).sort(); +}; + /*@ Ox.serialize Parses an object into query parameters > Ox.serialize({a: 1, b: 2, c: 3})