bugfix + added ability to pass value through STOP(..)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-11-14 19:41:00 +03:00
parent 78529b667b
commit 17c970319a
4 changed files with 40 additions and 29 deletions

View File

@ -566,6 +566,7 @@ sources(<object>, <name>, <callback>)
``` ```
callback(<source>) callback(<source>)
-> STOP -> STOP
-> STOP(<value>)
-> undefined -> undefined
-> <value> -> <value>
``` ```
@ -576,6 +577,9 @@ one of the following:
- `object.STOP` - `object.STOP`
This will make `sources(..)` stop and return the `<list>` up to and This will make `sources(..)` stop and return the `<list>` up to and
including the object that triggered the _stop_. including the object that triggered the _stop_.
- `object.STOP(<value>)`
Same as returning `object.STOP` but will put the `<value>` at the end of
the returned list instead of the input object.
- `undefined` - `undefined`
Add the object triggering `callback(..)` in `<list>` as-is and continue. Add the object triggering `callback(..)` in `<list>` as-is and continue.
- array - array
@ -625,6 +629,7 @@ values(<object>, <name>, <callback>, true)
``` ```
callback(<descriptor>, <source>) callback(<descriptor>, <source>)
-> STOP -> STOP
-> STOP(value)
-> undefined -> undefined
-> <value> -> <value>
``` ```

View File

@ -248,8 +248,9 @@ function(base, obj, non_strict){
// object to trigger iteration stop... // object to trigger iteration stop...
// //
module.STOP = // NOTE: this is a placeholder for documnetation/context purposes, see
{doc: 'stop iteration.'} // the actual implementation at the end of the module...
module.STOP = undefined
// Get a list of source objects for a prop/attr name... // Get a list of source objects for a prop/attr name...
@ -273,6 +274,7 @@ module.STOP =
// //
// callback(obj) // callback(obj)
// -> STOP // -> STOP
// -> STOP(value)
// -> .. // -> ..
// //
// //
@ -281,6 +283,8 @@ module.STOP =
// callback(..) return values: // callback(..) return values:
// - STOP - stop the search and return the match list terminated // - STOP - stop the search and return the match list terminated
// with the object triggering the stop. // with the object triggering the stop.
// - STOP(value) - stop the search and return the match list terminated
// with the value passed to STOP(..)
// - undefined - return the triggering object as-is // - undefined - return the triggering object as-is
// NOTE: this is the same as returning [obj] // NOTE: this is the same as returning [obj]
// - array - merge array content into the result insteaad of // - array - merge array content into the result insteaad of
@ -319,9 +323,12 @@ function(obj, name, callback){
res.push( res.push(
(o === undefined || o === module.STOP) ? (o === undefined || o === module.STOP) ?
[obj] [obj]
: o instanceof module.STOP ?
o.value
: o ) : o )
// stop... // stop...
if(o === module.STOP){ if(o === module.STOP
|| o instanceof module.STOP){
return res.flat() } } return res.flat() } }
obj = obj.__proto__ } obj = obj.__proto__ }
return res.flat() } return res.flat() }
@ -343,6 +350,7 @@ function(obj, name, callback){
// //
// callback(value/prop, obj) // callback(value/prop, obj)
// -> STOP // -> STOP
// -> STOP(value)
// -> .. // -> ..
// //
// //
@ -352,20 +360,6 @@ function(obj, name, callback){
// //
// //
// NOTE: for more docs on the callback(..) see sources(..) // NOTE: for more docs on the callback(..) see sources(..)
//
// XXX BUG: passing a callback here breaks the return value at the STOP...
// essentially this is a question of how can we return STOP and the
// value to be returned at the same time???
// ...ways to go:
// - store the last return from callback(..) and if it's STOP
// patch the last value (HACK-ish)
// - skip the last value...
// ...this will complicate the logic quite a bit as the user
// will need to STOP after the last position...
// - return STOP(value) or [STOP, value]
// ...requires the user not to forget...
// - ignore the callback return value...
// ...this seems the most uniform, but this can break things...
var values = var values =
module.values = module.values =
function(obj, name, callback, props){ function(obj, name, callback, props){
@ -385,11 +379,15 @@ function(obj, name, callback, props){
// wrap the callback if given... // wrap the callback if given...
var c = typeof(callback) == 'function' var c = typeof(callback) == 'function'
&& function(obj){ && function(obj){
return callback(_get(obj, name), obj) } var val = _get(obj, name)
var res = callback(val, obj)
return res === module.STOP ?
// wrap the expected stop result if the user did not do it...
module.STOP(val)
: res }
return c ? return c ?
// NOTE: we do not need to handle the callback return values as // NOTE: we do not need to handle the callback return values as
// this is fully done by c(..) in sources(..) // this is fully done by c(..) in sources(..)
// XXX BUG: if this stops the last value will be the obj and not the prop...
sources(obj, name, c) sources(obj, name, c)
: sources(obj, name) : sources(obj, name)
.map(function(obj){ .map(function(obj){
@ -668,8 +666,11 @@ function(base, object, callback){
res.push( res.push(
(o === undefined || o === module.STOP) ? (o === undefined || o === module.STOP) ?
[base] [base]
: o instanceof module.STOP ?
o.value
: o ) : o )
if(o === module.STOP){ if(o === module.STOP
|| o instanceof module.STOP){
return res.flat() } return res.flat() }
// match found, no need to test further... // match found, no need to test further...
break } } break } }
@ -1129,6 +1130,16 @@ function Constructor(name, a, b, c){
//---------------------------------------------------------------------
//
module.STOP = Constructor('STOP', {
doc: 'stop iteration.',
__init__: function(value){
this.value = value },
})
/********************************************************************** /**********************************************************************
* vim:set ts=4 sw=4 : */ return module }) * vim:set ts=4 sw=4 : */ return module })

View File

@ -1,6 +1,6 @@
{ {
"name": "ig-object", "name": "ig-object",
"version": "5.2.8", "version": "5.3.0",
"description": "", "description": "",
"main": "object.js", "main": "object.js",
"scripts": { "scripts": {

View File

@ -662,11 +662,6 @@ var cases = test.Cases({
// XXX essert ignores the order here -- this should fail... // XXX essert ignores the order here -- this should fail...
[123, 321], '.values(.., true) ') [123, 321], '.values(.., true) ')
// XXX BUG: this returns the object and not the value...
console.log('>>>>>', object.values(obj, 'x', function(){ return object.STOP }))
// XXX BUG: this returns the object and not the prop descriptor...
console.log('>>>>>', object.values(obj, 'x', function(){ return object.STOP }, true))
assert( assert(
object.values(obj, 'x', function(){ return object.STOP })[0] == 321, object.values(obj, 'x', function(){ return object.STOP })[0] == 321,
// XXX essert ignores the order here -- this should fail... // XXX essert ignores the order here -- this should fail...