DataProvider is not secretly decorating things, BUT something somewhere
in the V2 stuff is iterating over the array object itself, and is
silently blowing up when it finds these extra functions. I've had a
similar problem when some third party code was adding a function to
object.prototype, and the WebService object took a dump (it iterates
over a hash object and sees something weird and throws an error).
Anyway, the solution is to call ASSetPropFlags on the function so that
it is hidden. I heavily modified your class to make it more AS2
friendly, hope you don't mind! To use this class either call (once) :
ArrayEmpowerment.init();
or if you just want to decorate just one object:
ArrayEmpowerment.mixin(myobject);
I also check to see if the function exists before decorating and warn.
This way we'll know if there is a decorator conflict.
class ArrayEmpowerment extends Object{
private static var initialized:Boolean = false;
private static var mixins:ArrayEmpowerment = new ArrayEmpowerment();
private static var mixInProps:Array =
["any","clear","collect","compact","count","deleteAll","deleteAt","deleteIf","duplicate","each","eachIndex"
,"eql","every","fill","filter","flatten","has","index","indexes","last","map","nitems","replicate","reverseEach"
,"lastIndexOf","uniq","sum","mean","min","max"];
// inherent properties of array
var length : Number;
var splice : Function;
var slice : Function;
var sortOn : Function;
var reverse : Function;
var sort : Function;
/**
* Empowered Array - Decorates the Array class with all the
functions of this class.
*/
public static function init(){
if(initialized){ return; };
initialized = true;
// take all methods/props from our template object
// and put them on the prototype.
mixin(Array.prototype);
}
/**
* Instead of calling init, you may call mixin on an object, and it will
* decorate the object only, instead of Array.prototype.
*/
public static function mixin(obj:Object){
var m = mixInProps;
var l = m.length;
for (var i=0; i<l; i++) {
if(obj[m[i]]){
trace("WARNING!!!! Function:"+m[i]+" already exists!
Aborting mixin.");
}else{
obj[m[i]] = mixins[m[i]];
_global.ASSetPropFlags(obj, m[i],1);
}
}
}
// Runs a function on every item in the array
// Returns true if the function returns true for any one item
function any(block) {
var a = this.length;
while (--a -(-1)) {
if (block(this[a])) return true;
}
return false;
};
// Removes all elements from Array
function clear() {
this.length = 0;
};
// Invoking block once for every element, passing each element as a
// parameter to block
// The result of block is used as the given element in the array
function collect(block) {
var n = this.length;
for (var a = 0; a < n; a++) {
this[a] = block(this[a]);
}
};
// Removes all null and undefined elements from Array
function compact() {
var i = -1;
var n = this.length;
var r = [];
for (var a = 0; a < n; a++) {
if (this[a] != null && this[a] != undefined) {
r.push(this[a]);
}
}
};
// Returns the number of obj found in the Array.
function count(obj) {
var c = 0;
var a = this.length;
if (obj instanceof Array) {
while (--a -(-1)) {
if (this[a].eql(obj)) c++;
}
} else {
while (--a -(-1)) {
if (this[a] == obj) c++;
}
}
return c;
};
// Deletes items from the Array that are equal to obj
function deleteAll(obj) {
var n = this.length;
var r = [];
if (!(obj instanceof Array)) {
for (var a = 0; a < n; a++) {
if (this[a] == obj) r.push(this[a]);
}
} else {
for (var a = 0; a < n; a++) {
if (!this[a].eql(obj)) r.push(this[a]);
}
}
this.replicate(r);
};
// Deletes the element at the specified index, returning that element,
// or undefined if the index is out of range
function deleteAt(i) {
if (i < this.length && i > -1) return this.splice(i, 1)[0];
return undefined;
};
// Deletes every element of Array for which block evaluates to true
function deleteIf(block) {
var r = [];
var n = this.length;
for (var a = 0; a < n; a++) {
if (!block(this[a])) {
r.push(this[a]);
}
}
this.replicate(r);
};
// Returns a copy of the array
function duplicate() {
var r = [];
var a = this.length;
while (--a -(-1)) {
r[a] = this[a];
}
return r;
};
// Calls block once for each element in Array, passing that element as a
// parameter
function each(block) {
var n = this.length;
for (var a = 0; a < n; a++) {
block(this[a]);
}
};
// Same as Array.each, but passes the index of the element instead of
// the element itself
function eachIndex(block) {
var n = this.length;
for (var a = 0; a < n; a++) {
block(a);
}
};
// An array is equal to another array if the lengths are equal and each
// corresponding element is equal
function eql(arr) {
if (arr.length != this.length || !(arr instanceof Array)) {
return false;
} else {
var a = this.length;
while (--a -(-1)) {
if (this[a] instanceof Array) {
if (!this[a].eql(arr[a])) return false;
} else if (this[a] != arr[a]) {
return false;
}
}
}
return true;
};
// Runs block on every item in the array
// Returns true if the function returns true for every item
function every(block) {
var a = this.length;
while (--a -(-1)) {
if (!block(this[a])) return false;
}
return true;
};
// Sets the selected elements of Array (which may be the entire array)
// to obj
// A start of undefined is equivalent to zero.
// A length of undefined is equivalent to Array.length.
function fill(obj, start, len) {
if (!start) start = 0;
if (len == undefined) len = this.length;
len = start + len;
if (len > this.length) len = this.length;
while (--len - (-1) > start) {
this[len] = obj;
}
};
// Runs a function on every item in the array
// Returns an array of all items for which the function returns true.
function filter(block) {
var r = [];
var n = this.length;
for (var a = 0; a < n; a++) {
if (block(this[a])) r.push(this[a]);
}
return r;
};
// Returns a new array that is a one-dimensional flattening of this
// Array (recursively)
// That is, for every element that is an array, extract its elements
//into the new array
function flatten(r) {
if (!r) r = [];
var l = this.length;
for (var a = 0; a < l; a++) {
if (!(this[a] instanceof Array)) {
r.push(this[a]);
} else {
this[a].flatten(r);
}
}
return r;
};
// Returns true if the given obj is present in Array (if any element ==
// obj)
function has(obj) {
var a = this.length;
if (!(obj instanceof Array)) {
while (--a -(-1)) {
if (this[a] == obj) return true;
}
} else {
while (--a -(-1)) {
if (this[a].eql(obj)) return true;
}
}
return false;
};
// Returns the index of the first object in Array such that the object
// == obj.
// Returns undefined if no match is found
function index(obj) {
var a = this.length;
while (--a -(-1)) {
if (this[a] == obj) return a;
if (this[a] instanceof Array) {
if (this[a].eql(obj)) return a;
}
}
return undefined;
};
// Returns a new array consisting of elements at the given indices.
// May insert undefined for indices out of range.
function indexes() {
var r = [];
var l = arguments.length;
for (var a = 0; a < l; a++) {
if (arguments[a] > -1 && arguments[a] < this.length) {
r.push(this[arguments[a]]);
} else {
r.push(undefined);
}
}
return r;
};
// Synonym for Array.indexes
// Array.prototype.indices = Array.prototype.indexes;
//
// Returns the last element of Array. If the array is empty, returns
// undefined
function last() {
if (this.length > 0) return this[this.length - 1];
return undefined;
};
// Runs a function on every item in the array and returns the results in
// an array
function map(block) {
var r = [];
var n = this.length;
for (var a = 0; a < n; a++) {
r.push(block(this[a]));
}
return r;
};
// Returns the number of non-null/undefined elements in Array. May be
// zero
function nitems() {
var c = 0;
var a = this.length;
while (--a -(-1)) {
if (this[a] != null && this[a] != undefined) c++;
}
return c;
};
// Makes this array a copy of the passed array
function replicate(r) {
this.length = 0;
var a = r.length;
while (--a -(-1)) {
this[a] = r[a];
}
};
// Same as Array.each , but traverses Array in reverse order
function reverseEach(block) {
var n = this.length;
while(--n -(-1)) {
block(this[n]);
}
};
// Returns the index of the last object in Array such that the object ==
// obj
// Returns undefined if no match is found.
function lastIndexOf(obj) {
var a = this.length;
while (--a -(-1)) {
if (!(this[a] instanceof Array)) {
if (this[a] == obj) return a;
} else {
if (this[a].eql(obj)) return a;
}
}
return undefined;
};
// Returns a new array by removing duplicate values in Array.
function uniq() {
var r = [];
var l = this.length;
for (var a = 0; a < l; a++) {
if (!r.include(this[a])) r.push(this[a]);
}
return r;
};
// MATH METHODS
function sum() {
var x = 0;
var a = this.length;
while (--a -(-1)) {
var n = Number(this[a]);
if (!isNaN(n)) {
x += n;
} else {
return undefined;
}
}
return x;
};
function mean() {
var s = this.sum();
if (s != undefined) return this.sum() / this.length;
return undefined;
};
function min() {
var a = this.length;
if (!a) return undefined;
var x = this.last();
while (--a -(-1)) {
x = Math.min(this[a], x);
}
return x;
};
function max() {
var a = this.length;
if (!a) return undefined;
var x = this.last();
while (--a -(-1)) {
x = Math.max(this[a], x);
}
return x;
};
}
Chris Hill wrote:
Hmmm...it looks as though there are some name conflicts or something
between MM v2 Array mixins and your functions. I've got a DataGrid,
and as soon as I add the ArrayEmpowerment class, the data grid stops
working. I'm assuming that DataProvider's adding some methods with the
same names as your class.
http://training.figleaf.com
_______________________________________________
Flashcoders@chattyfig.figleaf.com
To change your subscription options or search the archive:
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Brought to you by Fig Leaf Software
Premier Authorized Adobe Consulting and Training
http://www.figleaf.com
http://training.figleaf.com