Mike Gerwitz
d9b86c1544
Traits can now override methods of their class supertypes. Previously, in order to override a method of some class `C` by mixing in some trait `T`, both had to implement a common interface. This had two notable downsides: 1. A trait that was only compatible with details of `C` could only work with `C#M` if it implemented an interface `I` that declared `I#M`. This required the author of `C` to create interfaces where they would otherwise not be necessary. 2. As a corollary of #1---since methods of interfaces must be public, it was not possible for `T` to override any protected method of `C`; this meant that `C` would have to declare such methods public, which may break encapsulation or expose unnecessary concerns to the outside world. Until documentation is available---hopefully in the near future---the test cases provide detailed documentation of the behavior. Stackable traits work as you would expect: ```javascript var C = Class( { 'virtual foo': function() { return 'C'; }, } ); var T1 = Trait.extend( C, { 'virtual abstract override foo': function() { return 'T1' + this.__super(); }, } ); var T2 = Trait.extend( C, { 'virtual abstract override foo': function() { return 'T2' + this.__super(); }, } ); C.use( T1 ) .use( T1 ) .use( T2 ) .use( T2 ) .foo(); // result: "T2T2T1T1C" ``` If the `override` keyword is used without `abstract`, then the super method is statically bound to the supertype, rather than being resolved at runtime: ```javascript var C = Class( { 'virtual foo': function() { return 'C'; }, } ); var T1 = Trait.extend( C, { 'virtual abstract override foo': function() { return 'T1' + this.__super(); }, } ); var T2 = Trait.extend( C, { // static override 'virtual override foo': function() { return 'T2' + this.__super(); }, } ); C.use( T1 ) .use( T1 ) .use( T2 ) .use( T2 ) .foo(); // result: "T2C" ``` This latter form should be discouraged in most circumstances (as it prevents stackable traits), but the behavior is consistent with the rest of the system. Happy hacking. |
||
---|---|---|
doc | ||
lib | ||
test | ||
tools | ||
.gitignore | ||
.mailmap | ||
COPYING | ||
HACKING | ||
Makefile.am | ||
README.md | ||
TODO | ||
configure.ac | ||
index.js | ||
package.json.in |
README.md
GNU ease.js
GNU ease.js is a classical object-oriented framework for Javascript, intended to eliminate boilerplate code and "ease" the transition into JavaScript from other object-oriented languages.
Current support includes:
- Simple and intuitive class definitions
- Classical inheritance
- Abstract classes and methods
- Interfaces
- Traits as mixins
- Visibility (public, protected, and private members)
- Static and constant members
Documentation
Comprehensive documentation and examples are available on the GNU ease.js website and in its manual.
Bug Reports / Feature Requests
Please direct bug reports and feature requests to bug-easejs@gnu.org or the project page on Savannah.
Why Classical OOP in JavaScript?
GNU ease.js was created (historically) for a number of reasons:
- To "ease" object-oriented developers into JavaScript by providing a familiar environment.
- To provide the maintenance and development benefits of classical OOP.
- To provide features not included in the language, such as proper encapsulation through private/protected members, interfaces, traits, intuitive inheritance, and other conveniences.
- To encapsulate the hacks commonly used to perform the above tasks.
Many JS purists believe that classical object-oriented programming should be left out of JavaScript and that one should stick strictly to prototypal development. While the two are related (they are both object-oriented), they can be applied to different problem domains in order to achieve results that are more natural or intuitive to developers; GNU ease.js works seamlessly with existing prototypes, allowing the developer to choose whether or not they want to use "classes".
Building and Installation
See INSTALL.
License
GNU ease.js is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
N.B.: Versions prior to 0.2.0 were released under the LGPLv3+. Upon becoming
a GNU project, it was relicensed under the GPLv3+ to help the FSF stand strong
in its fight against proprietary JavaScript. For more information, please see
the NEWS file (which can be built with make NEWS
).