TO DO - Uize
- Contents
- 1. Uize.pipe
- 2. Uize.log
- 3. Uize.own
- 4. Uize.try
- 5. Uize.warn
- 6. Uize.warnIfSlow
- 7. Uize.quantize
- 8. Uize.random
- 9. Uize.safe
- 10. Uize.cycleCalls
- 11. Uize.forEach
- 12. Uize.map
- 13. Uize.filter
- 14. Uize.keys
- 15. Uize.TreeWalker
- 16. Quick Win Additions (in order of priority / usefulness)
- 17. Uize.fox
- 18. Uize.willCall
- 19. Uize.watchMethod
- 20. Uize.memoize
- 21. Uize.constrain
- 22. Uize.reverseLookup
- 23. Uize.indexIn
- 24. Uize.module
- 25. Multiple Inheritance
- 26. Library Modules
- 27. Uize.clone
- 28. Uize.substituteInto
This is a TO DO document for the Uize
module.
1. Uize.pipe
Pipes a value through a series of processes.
The Uize.pipe
method makes it possible to express serial processing of values in forward rather than backwards order, and also eliminates the issue of cumulative indentation that is associated with nested function calls.
IMPLEMENTATION
_package.pipe = function () { for ( var _argumentNo = 0, _arguments = arguments, _argumentsLength = _arguments.length, _argument, _input = _arguments [0] ; ++_argumentNo < _argumentsLength; ) { _input = Uize.isArray (_argument = _arguments [_argumentNo]) ? _argument [0].apply (0,[_input].concat (_argument.slice (1))) : _argument (_input) ; } return _input; }
INSTEAD OF...
return Uize.Data.Csv.to ( Uize.Data.NameValueRecords.fromHash ( Uize.Loc.FileFormats.ProjectStrings.Util.flatten (_toEncode), 0, 1 ) );
USE...
return Uize.pipe ( _toEncode, Uize.Loc.FileFormats.ProjectStrings.Util.flatten, [Uize.Data.NameValueRecords.fromHash,0,1], Uize.Data.Csv.to );
2. Uize.log
Logs a message, using the configured logging options.
SYNTAX
Uize.log (messageSTR);
IMPLEMENTATION
_package.log = function (message) { // fill this in };
3. Uize.own
Would return the value of the own property of an object, but not a property value that is inherited from the object's prototype.
SYNTAX
valueANYTYPE = Uize.own (sourceOBJ,propertySTRorINT);
IMPLEMENTATION
_package.own = function (_source,_property) { var _result; return ( _source && (_result = _source [_property]) !== _undefined && _source.constructor.prototype [_property] !== _undefined && !_source.hasOwnProperty (_property) ? _undefined : _result ); };
4. Uize.try
Tries to execute the given function, executing the optional catch expression and warning, ignoring, or throwing any error that occurs.
SYNTAX
Uize.try (tryFUNC,catchFUNC);
IMPLEMENTATION
_package.warnForTryErrors = true; _package.ignoreUncaughtTryErrors = false; _package.try = function (_tryFunction,_catchFunction) { try { _tryFunction (); } catch (_error) { _package.warnForTryErrors && _package.warn (_error); if (_catchFunction) { _catchFunction (_error); } else if (!_package.ignoreUncaughtTryErrors) { throw _error; } } };
5. Uize.warn
Outputs to the log, depending on the configuration for warnings.
SYNTAX
Uize.warn (messageSTR);
IMPLEMENTATION
_package.logWarnings = true; _package.warn = function (_message) { _package.logWarnings && _package.log (_message); };
6. Uize.warnIfSlow
Warns if the specified function takes too long to complete (the function can be synchronous or asynchronous).
IMPLEMENTATION
_package.warnIfSlow = function (_function) { function _done () { } _function (_done); };
7. Uize.quantize
Quantizes the specified number to the specified quantum size.
IMPLEMENTATION
_package.quantize = function (_value,_quantum) { return _quantum ? Math.round (_value / _quantum) * _quantum : _value; };
8. Uize.random
Generates a random value from the specified range or list of possible values.
DIFFERENT USAGES
Generate a Random Number in the Range of Zero to One
randomNUM = Uize.random ();
Generate a Random Number in the Range of Zero to a Maximum Value
randomNUM = Uize.random (maxValueNUM);
Select a Random Value From a List of Possible Values
randomValueANYTYPE = Uize.random (valuesLIST);
Select a Random Characters From a Characters String
randomCharacterSTR = Uize.random (charactersSTR);
Generate a Random Integer in a Specified Range
randomINT = Uize.random (rangeLowerLimitINT,rangeUpperLimitINT);
Generate a Random Floating Point Number in a Specified Range
randomNUM = Uize.random (rangeLowerLimitNUM,rangeUpperLimitNUM,0);
Generate a Random, Custom Quantized Number in a Specified Range
randomNUM = Uize.random (rangeLowerLimitNUM,rangeUpperLimitNUM,quantumNUM);
IMPLEMENTATION
_package.random = function (_arg0,_arg1,_arg2) { var _random0to1 = Math.random (); function _randomIndex () { return Math.round ((_arg0.length - 1) * _random0to1); } return ( arguments.length > 1 ? _package.constrain ( _arg0 + _quantize ((_arg1 - _arg0) * _random0to1,_arg2 == _undefined ? 1 : _arg2), _arg0, _arg1 ) : _arg0 == _undefined ? _random0to1 : _package.isNumber (_arg0) ? Math.round (_random0to1 * _arg0) : _package.isList (_arg0) ? _arg0 [_randomIndex ()] : _package.isString (_arg0) ? _arg0.charAt (_randomIndex ()) : _random0to1 ); };
9. Uize.safe
Wraps a function in order to protect it from possible JavaScript errors during its execution.
IMPLEMENTATION
Uize.safe = function (_function,_returnValueIfError) { var _hasReturnValueIfError = arguments.length > 1; return function () { try { return _function.apply (this,arguments); } catch (_error) { return _hasReturnValueIfError ? _returnValueIfError : _error; } }; };
This method catches errors that occur in the function that is being wrapped, returning the error if no value is explicitly specified that should be returned when an errors occur.
10. Uize.cycleCalls
IMPLEMENTATION
Uize.cycleCalls = function () { var _functionNo = 0, _arguments = arguments, _totalFunctions = arguments.length ; return function () { _arguments [_functionNo].apply (this,arguments); _functionNo = (_functionNo + 1) % _totalFunctions; }; }
11. Uize.forEach
Update this method to support objects that have defined iterators.
12. Uize.map
Use native map function if available and _source is an array & _target is a new array | |
Add support for _source being a string? |
13. Uize.filter
Works much in the same way as Uize.map instead returns the matched set. Should use native filter function when appropriate.
14. Uize.keys
Use native Object.keys function if available |
15. Uize.TreeWalker
An object built into the Uize
base module that allows you to control walking through an object tree in a safe and performant way.
avoids reference loops / circular references | |
iterates without using recursion, to minimize function calls used for walking the tree |
16. Quick Win Additions (in order of priority / usefulness)
16.1. STILL TO DO
16.1.1. Uize.indexOf, Uize.lastIndexOf
essentially derived from indexIn, but adapted to also operate on strings and to use built-in indexOf when possible and supported by JavaScript built-in objects (i.e. newer versions of JavaScript) |
16.1.2. Uize.indexIn
adapt to add support for source being a string |
16.2. LATER
16.2.1. Uize.extend
alias of copyInto, for those who are more comfortable with the extend semantic |
16.2.2. Uize.ensureArray
ensures that the value is an array | |
if the value is already an array, then it is simply returned | |
if the value is an arguments object, then an array is created from it | |
if the value is any other type, then a new array is returned with the value as its single element | |
this is useful for methods that want to be versatile and support simple value types in addition to arrays, but want to normalize to array of one element for purpose of implementation code |
16.2.3. Uize.ensureIn
checks to see if an element is present, and adds it if not | |
supports adding at beginning or adding at end, with optional where parameter |
16.2.4. Uize.isStringy
returns true if the value is either a string primitive or an instance of a String object or "subclass" |
16.2.5. Uize.isTruthy
returns true if the value is truthy | |
useful for methods that accept value matchers |
16.2.6. Uize.isFalsy
returns true is the value is falsy | |
useful for methods that accept value matchers |
17. Uize.fox
Adds an x
property to a function to allow "function of x" value transformers to be easily manufactured from the function with specific values for the function's non-x arguments.
IMPLEMENTATION
Uize.wrap = function (_function) { return function () {return _function.apply (this,arguments)}; }; Uize.fox = function (_function,_wrapOriginal) { var _foxifiedFunc = _wrapOriginal ? Uize.wrap (_function) : _function; _foxifiedFunc.x = function () { var _arguments = Uize.copyList (arguments); return Uize.copyInto ( function (x) {return _function.apply (this,[x].concat (_arguments))}, { arguments:_arguments, getDisplayName:function () {return _foxifiedFunc.displayName || _function.name} } ); }; return _foxifiedFunc; };
17.1. Example 1
DEFINE
Uize.fox (Uize.inRange);
USE
var numbersIn0to100Range = Uize.filterArray (numbers,Uize.inRange.x (0,100));
17.2. Example 2
DEFINE
Uize.divide = Uize.fox (function (x,denominator) {return x / denominator});
USE
Uize.divide (10,2); Uize.divide.x (2);
17.3. Example 3
DEFINE
Uize.round = Uize.fox (Math.round,true); // wrap original, so as not to modify native function's properties
17.4. Example 4
DEFINE
Uize.isType = Uize.fox (function (x,type) {return typeof x == type});
USE
Uize.isNumber = Uize.isType.x ('number'); Uize.isString = Uize.isType.x ('string');
17.5. Usage Examples
function (x) {return Uize.Json.to (x,'mini')} (x) => {Uize.Json.to (x,'mini')} x => Uize.Json.to (x,'mini') Uize.Json.to.x ('mini')
18. Uize.willCall
Lets you conveniently create a function / method caller, where you can specify context, function, and arguments.
18.1. - names considered
callback | |
callerOf | |
willCall | |
performer | |
willDo | |
asCall | |
toCall | |
will | |
perform | |
callProxy | |
callAgent | |
funcCaller | |
funcAgent | |
funcProxy | |
handler | |
asHandler | |
asContext | |
makeCaller | |
doer |
IMPLEMENTATION
Uize.willCall = function (_context,_function,_arguments,_extraArgsMapping) { var _hasExtraArgsMapping = _extraArgsMapping != _undefined; if (_hasExtraArgsMapping) _arguments = _arguments ? _arguments.concat () : [] ; if (typeof _function == 'string') _function = _context [_function] ; return ( _hasExtraArgsMapping ? ( typeof _extraArgsMapping == 'number' ? function () { _arguments [_extraArgsMapping] = arguments [0]; return _function.apply (_context,_arguments); } // loop should be driven by _extraArgsMapping - not incoming arguments? // what about incoming arguments for which there are no mappings (i.e. beyond end of mapping array) : function () { for (var _argumentNo = arguments.length; --_argumentNo >= 0;) _arguments [_extraArgsMapping [_argumentNo]] = arguments [_argumentNo] ; return _function.apply (_context,_arguments); } ) : _arguments && _arguments.length ? function () {return _function.apply (_context,_arguments)} : function () {return _function.call (_context)} ); }; Uize.functionCall = function (_function,_arguments,_extraArgsMapping) { return Uize.willCall (0,_function,_arguments,_extraArgsMapping); };
EXAMPLE
var xSquared = Uize.willCall (Math.pow,[0,2],0), 3ToPowerX = Uize.willCall (Math.pow,[3,0],1) ;
INSTEAD OF...
var 3ToPowerX = function (x) {return Math.pow (3,x)};
USE...
var 3ToPowerX = Uize.willCall (Math.pow,[3,0],1);
19. Uize.watchMethod
Uize.watchFunction = function (_function,_before,_after) { return function () { _before && _before (this,arguments); var _result = _watched.apply (this,arguments); _after && _after (this,arguments,_result); return _result; }; }; Uize.watchMethod = function (_context,_methodName,_before,_after) { if (!Uize.isInstance (_context)) _context = _context.prototype ; var _watched = _context [_methodName], _watcher = _context [_methodName] = Uize.watchFunction (_watched) ; return { watch: function () {_context [_methodName] = _watcher}, unwatch: function () {_context [_methodName] = _watched} }; };
20. Uize.memoize
Uize.memoize = function (_function) { var _resultsCache = {}; return function () { var _cacheKey = Uize.Json.to (arguments); return ( _cacheKey in _resultsCache ? _resultsCache [_cacheKey] : (_resultsCache [_cacheKey] = _function.apply (this,arguments)) ); }; }; Uize.memoizeMethod = function (_context,_methodName) { // ... };
add ability to memoize a method (memoizeMethod) | |
consider supporting ability to dynamically unmemoize / turn memoization on or off | |
expose more granular memoization cache methods to allow functions to cache more discriminately | |
for basic memoization, support an optional function that can test the arguments values to determine whether or not memoization should be used for the specific call | |
consider supporting functions that may be asynchronous (i.e. use callbacks) | |
support ability to clear entire cache | |
support ability to invalidate cache for a specific set of argument values | |
idea: ability to count time saved as a result of memoization (i.e. keep track of number of times particular argument sets are encountered, and how long it took for first calculation) |
21. Uize.constrain
21.1. Support a wrap flag
Support a wrap flag, so that constrained values can be made to wrap around within the constraining range, rather than always only hitting up against the edges.
EXAMPLE USAGE
hue = Uize.constrain (hue,0,360,true);
IMPLEMENTATION THOUGHTS
var maxMinDelta = max - min; return ((value - min) % maxMinDelta + maxMinDelta) % maxMinDelta + min; // what about max < min?
21.2. Unbounded
Support either or both of the min and max boundaries being null
or undefined
.
22. Uize.reverseLookup
22.1. Support values for source being arrays.
EXAMPLE
Uize.reverseLookup ({ vegetable:['potato','tomato'], fruit:['apple','orange'] });
OUTPUT
{ potato:'vegetable', tomato:'vegetable', apple:'fruit', orange:'fruit' }
22.2. Support multiple values for source being the same
EXAMPLE
Uize.reverseLookup ({ potato:'vegetable', tomato:'vegetable', apple:'fruit', orange:'fruit' });
OUTPUT
{ vegetable:['potato','tomato'], fruit:['apple','orange'] }
22.3. Support Merging in to Target
23. Uize.indexIn
23.1. Support Simple Type Source
For simple type source, could do string index.
In this mode, fromEndBOOL
parameter could control choice of indexOf
vs lastIndexOf
, and strictEqualityBOOL
parameter could control case sensitivity.
24. Uize.module
24.1. Support Code Besides in Module Loader
How can code require a module that is not in the modules directory (like a code beside)?
What about by specifying a path (relative to the current file) in parentheses in the module name?
25. Multiple Inheritance
Consider a facility to support multiple inheritance (may involve creating a merge service for merging data from one object into another, since it should be possible to merge additional features of a different class into an already created class, and perhaps that merge feature would also be used in the _subclass function's implementation).
26. Library Modules
26.1. Library of Dispersed Modules
Can library modules that are outside the modules directory require modules that are outside the modules directory?
27. Uize.clone
27.1. Uize.clone and Circular References
Handle circular references in Uize.clone
(how to generate properties that are references to other parts of structure in same relationship as the equivalent property in the cloning source???)
28. Uize.substituteInto
optimize for successive substitution on the same source using the same form of map (but different values, of course) |
idea: a way to track whether a user originated an event. Sufficient to check on the presence of domEvent property? domEvent property should be propagated all the way up. |