On Jan 13, 3:20 pm, Matthieu Riou <[EMAIL PROTECTED]> wrote:
> I was wondering if anybody had thought of implementing Object.watch in
> Rhino. It's non-standard but pretty convenient, given that there's no
> way to override '=' in JS and already exists in SpiderMonkey:
I am pretty sure you can do everything you can do with watch with
__defineSetter__ and __lookupSetter__.
In fact, it might even be possible to implement watch in script code
in terms of __defineSetter__. I have a method that allows you to
deprecate a property (and basically execute an arbitrary callback any
time the property is accessed, which is why I bring it up) using only
the getter/setter APIs. (I've pasted the code below -- not sure if it
works on all cases but I haven't found any that it doesn't.)
I do not have an opinion on your original question -- whether to
implement watch. At least not yet.
==sample code==
if (typeof(object[property]) == "function") {
var deprecateFunction = function(f) {
return function() {
warning({ target: object, name: property, call:
arguments, reason:
reason });
// TODO Add regression to cover previous
mistake of not returning
this value (but invoking and then returning
// undefined)
return f.apply(this,arguments);
}
}
object[property] = deprecateFunction(object[property]);
return;
}
// If object has neither getter nor setter, we create both with
versions that cooperate with one another
// If object has custom getter and/or custom setter, we overwrite both
with versions that wrap them with warnings
if (!object.__lookupGetter__(property) && !
object.__lookupSetter__(property)) {
var values = new function() {
var value = object[property];
this.set = function(v) {
warning({ target: object, name: property, set: v,
reason:
reason });
value = v;
}
this.get = function() {
warning({ target: object, name: property, get: value,
reason:
reason });
return value;
}
}
object.__defineGetter__(property,values.get);
object.__defineSetter__(property,values.set);
} else {
var wrapSetter = function(f) {
return function(value) {
warning({ target: object, name: property, set: value,
reason:
reason });
if (f) {
f.apply(this, [ value ]);
}
}
}
var wrapGetter = function(f) {
return function() {
var rv;
if (f) {
rv = f.apply(this, []);
}
warning({ target: object, name: property, get: rv,
reason:
reason });
return rv;
}
}
object.__defineGetter__(property,wrapGetter(object.__lookupGetter__(property)));
object.__defineSetter__(property,wrapSetter(object.__lookupSetter__(property)));
}
==end sample code==
-- David P. Caldwell
http://www.inonit.com/
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino