Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Fast generics #11

Closed
wants to merge 3 commits into
from
View
@@ -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){
+ this[key] = method
+
+ this.prototype[key] = function(){
+ if (!arguments.length) return method.call(this, this)
+ var args = [this]
+ args.push.apply(args, arguments)
+ return method.apply(this, args)
+ }
+
+ g.prototype[key] = function(){
+ var args = [this.valueOf()]
+ args.push.apply(args, arguments)
+ return shell(method.apply(this, args))
+ }
+ }, 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
@@ -7,42 +7,42 @@ var array = require("../es5/array")
// set, get, count, each, map, filter, every, some, index, merge, remove, keys, values
-module.exports = array.implement({
+module.exports = array.implementGenerics({
- set: function(i, value){
- this[i] = value
- return this
+ set: function(self, i, value){
+ self[i] = value
+ return self
},
- get: function(i){
- return (i in this) ? this[i] : null
+ get: function(self, i){
+ return (i in self) ? self[i] : null
},
- count: function(){
- return this.length
+ count: function(self){
+ return self.length
},
- each: function(method, context){
- for (var i = 0, l = this.length; i < l; i++){
- if (i in this && method.call(context, this[i], i, this) === false) break
+ each: function(self, method, context){
+ for (var i = 0, l = self.length; i < l; i++){
+ if (i in self && method.call(context, self[i], i, self) === false) break
}
- return this
+ return self
},
- backwards: function(method, context){
- for (var i = this.length - 1; i >= 0; i--){
- if (i in this && method.call(context, this[i], i, this) === false) break
+ backwards: function(self, method, context){
+ for (var i = self.length - 1; i >= 0; i--){
+ if (i in self && method.call(context, self[i], i, self) === false) break
}
- return this
+ return self
},
- index: function(value){
- var index = array.indexOf(this, value)
+ index: function(self, value){
+ var index = array.indexOf(self, value)
return index === -1 ? null : index
},
- remove: function(i){
- return array.splice(this, i, 1)[0]
+ remove: function(self, i){
+ return array.splice(self, i, 1)[0]
}
})
View
@@ -5,25 +5,24 @@ number
var number = require("../es5/number")
-module.exports = number.implement({
+module.exports = number.implementGenerics({
- limit: function(min, max){
- return Math.min(max, Math.max(min, this));
+ limit: function(self, min, max){
+ return Math.min(max, Math.max(min, self));
},
- round: function(precision){
+ round: function(self, precision){
precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0)
- return Math.round(this * precision) / precision
+ return Math.round(self * precision) / precision
},
- times: function(fn, context){
- for (var i = 0; i < this; i++) fn.call(context, i, null, this)
- return this
+ times: function(self, fn, context){
+ for (var i = 0; i < self; i++) fn.call(context, i, null, self)
+ return self
},
- random: function(max){
- return Math.floor(Math.random() * (max - this + 1) + this)
+ random: function(self, max){
+ return Math.floor(Math.random() * (max - self + 1) + self)
}
-
})
View
@@ -8,65 +8,65 @@ var prime = require("../index"),
// set, get, count, each, map, filter, every, some, index, merge, remove, keys, values
-object.implement({
+object.implementGenerics({
- set: function(key, value){
- this[key] = value
- return this
+ set: function(self, key, value){
+ self[key] = value
+ return self
},
- get: function(key){
- var value = this[key]
+ get: function(self, key){
+ var value = self[key]
return value != null ? value : null
},
- count: function(){
+ count: function(self){
var length = 0
- prime.each(this, function(){
+ prime.each(self, function(){
length++
})
return length
},
- each: function(method, context){
- return prime.each(this, method, context)
+ each: function(self, method, context){
+ return prime.each(self, method, context)
},
- map: function(method, context){
+ map: function(self, method, context){
var results = {}
- prime.each(this, function(value, key, self){
+ prime.each(self, function(value, key, self){
results[key] = method.call(context, value, key, self)
})
return results
},
- filter: function(method, context){
+ filter: function(self, method, context){
var results = {}
- prime.each(this, function(value, key, self){
+ prime.each(self, function(value, key, self){
if (method.call(context, value, key, self)) results[key] = value
})
return results
},
- every: function(method, context){
+ every: function(self, method, context){
var every = true
- prime.each(this, function(value, key, self){
+ prime.each(self, function(value, key, self){
if (!method.call(context, value, key, self)) return every = false
})
return every
},
- some: function(method, context){
+ some: function(self, method, context){
var some = false
- prime.each(this, function(value, key, self){
+ prime.each(self, function(value, key, self){
if (!some && method.call(context, value, key, self)) return !(some = true)
})
return some
},
- index: function(value){
+ index: function(self, value){
var key = null
- prime.each(this, function(match, k){
+ prime.each(self, function(match, k){
if (value === match){
key = k
return false
@@ -75,23 +75,23 @@ object.implement({
return key
},
- remove: function(key){
- var value = this[key]
- delete this[key]
+ remove: function(self, key){
+ var value = self[key]
+ delete self[key]
return value
},
- keys: function(){
+ keys: function(self){
var keys = []
- prime.each(this, function(value, key){
+ prime.each(self, function(value, key){
keys.push(key)
})
return keys
},
- values: function(){
+ values: function(self){
var values = []
- prime.each(this, function(value, key){
+ prime.each(self, function(value, key){
values.push(value)
})
return values
View
@@ -5,36 +5,36 @@ string methods
var string = require("../es5/string")
-string.implement({
+string.implementGenerics({
- clean: function(){
- return string.trim((this + "").replace(/\s+/g, " "))
+ clean: function(self){
+ return string.trim((self + "").replace(/\s+/g, " "))
},
- camelize: function(){
- return (this + "").replace(/-\D/g, function(match){
+ camelize: function(self){
+ return (self + "").replace(/-\D/g, function(match){
return match.charAt(1).toUpperCase()
})
},
- hyphenate: function(){
- return (this + "").replace(/[A-Z]/g, function(match){
+ hyphenate: function(self){
+ return (self + "").replace(/[A-Z]/g, function(match){
return '-' + match.toLowerCase()
})
},
- capitalize: function(){
- return (this + "").replace(/\b[a-z]/g, function(match){
+ capitalize: function(self){
+ return (self + "").replace(/\b[a-z]/g, function(match){
return match.toUpperCase()
})
},
- escape: function(){
- return (this + "").replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1")
+ escape: function(self){
+ return (self + "").replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1")
},
- number: function(){
- return parseFloat(this)
+ number: function(self){
+ return parseFloat(self)
}
})
View
@@ -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){