Boom. I'm dividing this into two parts, one's a quick answer and quick fix, and the other's an explanation on the whole thing for future reference.
Quick Answer and Quick Fix ========================== It's a bug in Rhino (#510504, https://bugzilla.mozilla.org/show_bug.cgi?id=510504). You have 3 choices for fixes: 1. If you're using the current MooTools release and you're okay with editing -Core, search for the Object.reset function under 'Class.js' and remove the line `delete object[key];` inside that function. That's it. 2. If you're not comfortable with editing -Core, download and build the MooTools2 code on Github or the new MooTools build that has the Moo2 -core files (also on Github), build and use that. It doesn't have that particular line in the reset code. Done. 3. If you don't want any headaches in the future, patch Rhino with the patch included in the Bugzilla page: https://bugzilla.mozilla.org/attachment.cgi?id=394500&action=edit. Boom. And that's it. Explanation =========== When you create new class instances via the `new` operator and a constructor function, a new object is created and passed to your function. This is the actual class instance, available via `this`. >From the moment the class instance is created, its `prototype` property is already set, meaning it's already inheriting from your class. A common misconception when using MooTools is that the `initialize` property you put in your class declaration will become the constructor function for your object. While this might be so, MooTools actually wraps your `initialize` method inside another function that does some basic housekeeping magic for your classes (and this wrapper function is what actually becomes the constructor). One of the functions invoked inside this wrapper function is `Object.reset`, which does some basic cleanup for your classes. The "offending" line that's causing the problem is that `delete object [key];` right after the loop. As you might have guessed, this line doesn't actually do anything. There are certain items that can't actually be deleted by the `delete` operator, most of which are marked in the ECMA 262 specs as `DontDelete`. Another gotcha is that you can't delete an item that an object inherits via its prototype. This is the reason why `delete object[key];` doesn't do anything--the `object` there is the new instance object created because of the `new` operator. It's a blank object that doesn't have its own properties but instead inherits them from your class, so deleting it won't work. Now that's the problem with Rhino. Unlike other JavaScript engines, Rhino *actually* deletes the property. This is because Rhino reads the actual inheritance chain of the object until it find the property and deletes it. And that's the big bug: it actually deletes the prototypal item directly--which causes all other instances to lose the same property. And so, I offered you the three solutions above. You can either remove the delete line from your current MooTools source to get it working, or use the newer versions that don't have that line. But the best solution would be to patch Rhino itself. Hope that clears it up. Mark http://keetology.com/ P.S: Natives aren't affected by this because they don't use `delete` anywhere in the Native constructor, which is why everything else seems to work in Rhino, except for Classes. ------------------------------------------------------------------------------------------------- On Dec 4, 6:18 am, Matthew Beale <[email protected]> wrote: > Hi all, > > Is anyone using mootools server-side with Rhino? I was creating classes > with base.js but wanted to move to mootools... but though mootool's > methods are showing up fine: > > js> (new Array).each > function forEach() { [native code for Array.forEach, arity=1] } > > My classes are "missing" their instance methods > > js> (new Dataset).each_datapoint > js> > > The code is nothing special: > > var Dataset = new Class({ > > initialize: function( id ) { > // yeah > }, > > get: function( attr ) { > // yeah > }, > > each_datapoint: function( each_datapoint_function ) { > // exactly, nothing special! > } > > }); > > However if I add a class method with extend... > > Dataset.extend({ > foo: function(a){ > return a + 3; > } > > }); > > I can see the method just fine: > > js> Dataset.foo > > function (a) { > return a + 3; > > } > > Thoughts? This is wacky. > > -- > Matthew Beale :: 607 227 0871 > Resume & Portfolio @http://madhatted.com
