Created
April 29, 2011 12:39
-
-
Save fd/948234 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Curry a JS function. | |
* | |
* Note: | |
* Curry doesn't change `this`. | |
* | |
* Example: | |
* function f(a, b, c){ | |
* return [a, b, c]; | |
* }; | |
* var g = f.curry('a', 'b'); | |
* g('c'); # => ['a', 'b', 'c'] | |
*/ | |
Function.prototype.curry = function(){ | |
var curry_arguments = Array.prototype.slice.apply(arguments) | |
, base_function = this | |
; | |
return function(){ | |
var arguments = Array.prototype.slice.apply(arguments) | |
; | |
return base_function.apply(this, curry_arguments.concat(arguments)); | |
}; | |
}; | |
/* | |
* Bind a JS function. | |
* | |
* Example: | |
* function f(){ | |
* return "Hello " + this; | |
* }; | |
* var g = f.bind('Anais'); | |
* g(); # => "Hello Anais" | |
*/ | |
Function.prototype.bind = function(receiver){ | |
var base_function = this | |
; | |
return function(){ | |
var arguments = Array.prototype.slice.apply(arguments) | |
; | |
return base_function.apply(receiver, arguments); | |
}; | |
}; | |
var _default_chainer_target; | |
/* | |
* Create a chainer. | |
* | |
* Example: | |
* var _ = Function.chainer( | |
* { hello: function(self){ console.log("Hello " + self); } | |
* , bye: function(self){ console.log("Bye " + self); } | |
* }); | |
* _('Anais').hello().bye(); | |
* # console: | |
* # Hello Anais | |
* # Bye Anais | |
* | |
* Example: | |
* Function.chainer( | |
* String.prototype, | |
* { hello: function(self){ console.log("Hello " + self); } | |
* , bye: function(self){ console.log("Bye " + self); } | |
* }); | |
* 'Anais'.hello().bye(); | |
* # console: | |
* # Hello Anais | |
* # Bye Anais | |
* | |
* Example: | |
* var gf = "Anais"; | |
* Function.chainer( | |
* gf, | |
* { hello: function(self){ console.log("Hello " + self); } | |
* , bye: function(self){ console.log("Bye " + self); } | |
* }); | |
* gf.hello().bye(); | |
* # console: | |
* # Hello Anais | |
* # Bye Anais | |
*/ | |
Function.chainer = function(target, functions){ | |
var chainer = target | |
; | |
if (functions === undefined){ | |
functions = target; | |
chainer = _default_chainer_target() | |
target = chainer.prototype; | |
} | |
var name | |
; | |
for (name in functions) { | |
(function(name, func){ | |
target[name] = function(){ | |
var arguments = Array.prototype.slice.apply(arguments) | |
, use_member = false | |
; | |
try { | |
use_member = (this instanceof chainer); | |
} catch (e) {}; | |
if (use_member) { | |
func.apply(functions, [this.receiver].concat(arguments)); | |
return this; | |
} else { | |
func.apply(functions, [this].concat(arguments)); | |
return this; | |
} | |
}; | |
}(name, functions[name])); | |
} | |
return chainer; | |
}; | |
_default_chainer_target = function(){ | |
var base | |
; | |
base = function(receiver){ | |
if (this instanceof base) { | |
this.receiver = receiver; | |
} else { | |
return new base(receiver); | |
} | |
}; | |
return base; | |
}; | |
/* | |
* Easy duck typing for JS objects. | |
* | |
* Example: | |
* var f = Function.duck('concat'); | |
* var g = f.bind(['a']); | |
* g(['b']); # => ['a', 'b'] | |
* | |
* Example: | |
* var f = Function.duck('concat'); | |
* var g = f.bind(5); | |
* g(['b']); # => undefined | |
*/ | |
Function.duck = function(function_name){ | |
return function(){ | |
var member | |
; | |
member = this[function_name]; | |
if (member == undefined) { return; } | |
if (!(member instanceof Function)) { return; } | |
return member.apply(this, arguments); | |
}; | |
}; | |
/* | |
* Fire a function only once. | |
* | |
*/ | |
Function.prototype.once = function(){ | |
var base_function = this | |
, fired = false | |
, result = null | |
; | |
return function(){ | |
var arguments = Array.prototype.slice.apply(arguments) | |
; | |
if (!fired) { | |
result = base_function.apply(this, arguments); | |
} | |
return result; | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment