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

Reply via email to