Permalink
Browse files

Implement shell.implementGenerics, which optimizes for the common gen…

…eric case.

This means that after array.implementGenerics({foo: fn}), array.foo === fn.
  • Loading branch information...
1 parent 1bbf772 commit 30f02091adc669c7a761042be9c66e0df6e8ce8a @arian committed Mar 2, 2013
Showing with 48 additions and 1 deletion.
  1. +23 −1 shell.js
  2. +25 −0 test/shell/index.js
View
24 shell.js
@@ -36,7 +36,7 @@ var register = function(){
var g = prime({inherits: ghost})
- return prime({
+ var type = prime({
constructor: function(self){
return new g(self)
@@ -60,6 +60,28 @@ var register = function(){
})
+ type.implementGenerics = function(methods){
+ prime.each(methods, function(method, key){
@jdalton
jdalton added a line comment Mar 2, 2013

The use of prime.define is troubling. It causes inconsistencies between old and new enviros and unexpected behavior for non-own-properties by providing a default descriptor instead of using the non-own-property's descriptor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ prime.define(this, key, {
+ writable: true,
+ enumerable: true,
+ configurable: true,
+ value: method
+ })
@jdalton
jdalton added a line comment Mar 2, 2013

Besides, the use of prime.define is extraneous here because it's the default descriptor for assignments; this[key] = ... would do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ this.prototype[key] = function(){
+ return arguments.length ? method.apply(this, [this].concat(slice.call(arguments))) : method.call(this, this)
+ }
+
+ g.prototype[key] = function(){
+ return shell(method.apply(this, [this.valueOf()].concat(slice.call(arguments))))
@jdalton
jdalton added a line comment Mar 2, 2013

instead of creating a temporary array [this.valueOf] and also a temporary array slice.call(arguments) which have to get GC'ed you can change it to var args = [this.valueOf]; push.apply(args, arguments). (assumes push is defined elsewhere).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ }, this)
+ return this
+ }
+
+ return type
+
}
for (var types = "string,number,array,object,date,function,regexp".split(","), i = types.length; i--;) shell[types[i]] = register()
View
25 test/shell/index.js
@@ -13,6 +13,31 @@ describe('shell', function(){
setTimeout(done, 0)
})
+ it('should implement generic functions', function(){
+ var a = [1, 2], b = []
+
+ var array = ghost.array.implementGenerics({
+ __justATestMethod: function(self){
+ self.push(1)
+ return self
+ },
+ __otherTestMethod: function(self, a, b){
+ self.push(a + b)
+ return self
+ }
+ })
+
+ expect(array == ghost.array).to.be.ok()
+
+ expect(array.__justATestMethod(a)).to.eql([1, 2, 1])
+ expect(array.prototype.__justATestMethod.call(a)).to.eql([1, 2, 1, 1])
+ expect(array(a).__justATestMethod().valueOf()).to.eql([1, 2, 1, 1, 1])
+
+ expect(array.__otherTestMethod(b, 2, 3)).to.eql([5])
+ expect(array.prototype.__otherTestMethod.call(b, 3, 3)).to.eql([5, 6])
+ expect(array(b).__otherTestMethod(3, 4).valueOf()).to.eql([5, 6, 7])
+ })
+
it('should ghost types for chaining methods', function(){
expect(ghost([1, 2, 3]).join().valueOf()).to.equal('1,2,3')
expect(ghost(' 1,A,F ').trim().split(',').map(function(value){

0 comments on commit 30f0209

Please sign in to comment.