Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petsel/5592016 to your computer and use it in GitHub Desktop.
Save petsel/5592016 to your computer and use it in GitHub Desktop.
prototypal implementations of one full set and two complementary partial sets of AOP inspired method modifiers - [Function.prototype.before], [Function.prototype.after], [Function.prototype.afterThrowing], [Function.prototype.afterFinally] and [Function.prototype.around].
/**
* see also / derived from:
* [https://github.com/petsel/composable/blob/master/src/components/Controllable/Controllable.adviceTypes.afterThrowing-afterFinally.js]
* [https://github.com/petsel/composable/blob/master/src/composites/Function/Function.modifiers.adviceTypes.afterThrowing-afterFinally.js]
*/
(function (Function) {
"use strict";
var
ControllableMixin,
isFunction = function (type) {
return ((typeof type == "function") && (typeof type.call == "function") && (typeof type.apply == "function"));
},
makeModificationAfterThrowing = function (proceed, behavior, target, joinpoint) { // afterThrowing
return function () {
var ret, args = arguments;
try {
ret = proceed.apply(target, args);
} catch (exc) {
behavior.call(target, exc, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
//throw exc;
}
return ret;
};
},
makeModificationAfterFinally = function (proceed, behavior, target, joinpoint) { // afterFinally
return function () {
var ret, err, args = arguments;
try {
ret = proceed.apply(target, args);
} catch (exc) {
err = exc;
} // finally { ... }
ret = (err || ret);
behavior.call(target, ret, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return ret;
};
},
getSanitizedTarget = function (target) {
return (!target && ((target === void 0) || (target === null))) ? null : target;
},
afterThrowing = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterThrowing(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
},
afterFinally = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterFinally(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
}
;
ControllableMixin = function () {
var controllable = this;
controllable.afterThrowing = afterThrowing;
controllable.afterFinally = afterFinally;
};
ControllableMixin.call(Function.prototype);
}(Function));
/*
[http://closure-compiler.appspot.com/home]
- Simple - 621 byte
(function(g){var d=function(a){return"function"==typeof a&&"function"==typeof a.call&&"function"==typeof a.apply},l=function(a,f,b,d){return function(){var e,h=arguments;try{e=a.apply(b,h)}catch(c){f.call(b,c,h,d)}return e}},m=function(a,f,b,d){return function(){var e,c,k=arguments;try{e=a.apply(b,k)}catch(g){c=g}e=c||e;f.call(b,e,k,d);return e}},c=function(a){return a||void 0!==a&&null!==a?a:null},n=function(a,f,b){return d(this)&&d(a)&&l(this,a,c(f),c(b))||this},p=function(a,f,b){return d(this)&&d(a)&&m(this,a,c(f),c(b))||this};(function(){this.afterThrowing=n;this.afterFinally=p}).call(g.prototype)})(Function);
*/
/**
* see also / derived from:
* [https://github.com/petsel/composable/blob/master/src/components/Controllable/Controllable.adviceTypes.before-after-around.js]
* [https://github.com/petsel/composable/blob/master/src/composites/Function/Function.modifiers.adviceTypes.before-after-around.js]
*/
(function (Function) {
"use strict";
var
ControllableMixin,
isFunction = function (type) {
return ((typeof type == "function") && (typeof type.call == "function") && (typeof type.apply == "function"));
},
makeModificationBefore = function (proceed, behavior, target, joinpoint) { // before
return function () {
var args = arguments;
behavior.call(target, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return proceed.apply(target, args);
};
},
makeModificationAfterReturning = function (proceed, behavior, target, joinpoint) { // after - implemented as afterReturning
return function () {
var ret, args = arguments;
ret = proceed.apply(target, args);
behavior.call(target, ret, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return ret;
};
},
makeModificationAround = function (proceed, behavior, target, joinpoint) { // around
return function () {
return behavior.call(target, proceed, behavior, arguments, joinpoint/*provided by and passed only from within aspect oriented systems*/);
};
},
getSanitizedTarget = function (target) {
return (!target && ((target === void 0) || (target === null))) ? null : target;
},
before = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedAfter = this;
return ((
isFunction(proceedAfter) && isFunction(adviceHandler)
&& makeModificationBefore(proceedAfter, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedAfter);
},
after/*Returning*/ = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterReturning(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
},
around = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedEnclosed = this;
return ((
isFunction(proceedEnclosed) && isFunction(adviceHandler)
&& makeModificationAround(proceedEnclosed, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedEnclosed);
}
;
ControllableMixin = function () {
var controllable = this;
controllable.before = before;
controllable.after = after/*Returning*/;
controllable.around = around;
};
ControllableMixin.call(Function.prototype);
}(Function));
/*
[http://closure-compiler.appspot.com/home]
- Simple - 714 byte
(function(g){var b=function(a){return"function"==typeof a&&"function"==typeof a.call&&"function"==typeof a.apply},h=function(a,e,c,b){return function(){var d=arguments;e.call(c,d,b);return a.apply(c,d)}},k=function(a,e,c,d){return function(){var b,f=arguments;b=a.apply(c,f);e.call(c,b,f,d);return b}},l=function(a,b,c,d){return function(){return b.call(c,a,b,arguments,d)}},d=function(a){return a||void 0!==a&&null!==a?a:null},m=function(a,e,c){return b(this)&&b(a)&&h(this,a,d(e),d(c))||this},n=function(a,e,c){return b(this)&&b(a)&&k(this,a,d(e),d(c))||this},p=function(a,e,c){return b(this)&&b(a)&&l(this,a,d(e),d(c))||this};(function(){this.before=m;this.after=n;this.around=p}).call(g.prototype)})(Function);
*/
/**
* see also / derived from:
* [https://github.com/petsel/composable/blob/master/src/components/Controllable/Controllable.adviceTypes.before-after-throwing-finally-around.js]
* [https://github.com/petsel/composable/blob/master/src/composites/Function/Function.modifiers.adviceTypes.before-after-throwing-finally-around.js]
*/
(function (Function) {
"use strict";
var
ControllableMixin,
isFunction = function (type) {
return ((typeof type == "function") && (typeof type.call == "function") && (typeof type.apply == "function"));
},
makeModificationBefore = function (proceed, behavior, target, joinpoint) { // before
return function () {
var args = arguments;
behavior.call(target, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return proceed.apply(target, args);
};
},
makeModificationAfterReturning = function (proceed, behavior, target, joinpoint) { // after - implemented as afterReturning
return function () {
var ret, args = arguments;
ret = proceed.apply(target, args);
behavior.call(target, ret, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return ret;
};
},
makeModificationAfterThrowing = function (proceed, behavior, target, joinpoint) { // afterThrowing
return function () {
var ret, args = arguments;
try {
ret = proceed.apply(target, args);
} catch (exc) {
behavior.call(target, exc, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
//throw exc;
}
return ret;
};
},
makeModificationAfterFinally = function (proceed, behavior, target, joinpoint) { // afterFinally
return function () {
var ret, err, args = arguments;
try {
ret = proceed.apply(target, args);
} catch (exc) {
err = exc;
} // finally { ... }
ret = (err || ret);
behavior.call(target, ret, args, joinpoint/*provided by and passed only from within aspect oriented systems*/);
return ret;
};
},
makeModificationAround = function (proceed, behavior, target, joinpoint) { // around
return function () {
return behavior.call(target, proceed, behavior, arguments, joinpoint/*provided by and passed only from within aspect oriented systems*/);
};
},
getSanitizedTarget = function (target) {
return (!target && ((target === void 0) || (target === null))) ? null : target;
},
before = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedAfter = this;
return ((
isFunction(proceedAfter) && isFunction(adviceHandler)
&& makeModificationBefore(proceedAfter, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedAfter);
},
after/*Returning*/ = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterReturning(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
},
afterThrowing = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterThrowing(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
},
afterFinally = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedBefore = this;
return ((
isFunction(proceedBefore) && isFunction(adviceHandler)
&& makeModificationAfterFinally(proceedBefore, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedBefore);
},
around = function (adviceHandler/*:function*/, target/*:object(optional, but recommended to be applied)*/, joinpoint/*:Joinpoint(optional)*/) {
var proceedEnclosed = this;
return ((
isFunction(proceedEnclosed) && isFunction(adviceHandler)
&& makeModificationAround(proceedEnclosed, adviceHandler, getSanitizedTarget(target), getSanitizedTarget(joinpoint))
) || proceedEnclosed);
}
;
ControllableMixin = function () {
var controllable = this;
controllable.before = before;
controllable.after = after/*Returning*/;
controllable.afterThrowing = afterThrowing;
controllable.afterFinally = afterFinally;
controllable.around = around;
};
ControllableMixin.call(Function.prototype);
}(Function));
/*
[http://closure-compiler.appspot.com/home]
- Simple - 1124 byte
(function(h){var d=function(a){return"function"==typeof a&&"function"==typeof a.call&&"function"==typeof a.apply},l=function(a,e,c,d){return function(){var f=arguments;e.call(c,f,d);return a.apply(c,f)}},m=function(a,e,c,d){return function(){var f,b=arguments;f=a.apply(c,b);e.call(c,f,b,d);return f}},n=function(a,e,c,d){return function(){var f,b=arguments;try{f=a.apply(c,b)}catch(g){e.call(c,g,b,d)}return f}},p=function(a,e,c,d){return function(){var b,k,g=arguments;try{b=a.apply(c,g)}catch(h){k=h}b=k||b;e.call(c,b,g,d);return b}},q=function(a,b,c,d){return function(){return b.call(c,a,b,arguments,d)}},b=function(a){return a||void 0!==a&&null!==a?a:null},r=function(a,e,c){return d(this)&&d(a)&&l(this,a,b(e),b(c))||this},s=function(a,e,c){return d(this)&&d(a)&&m(this,a,b(e),b(c))||this},t=function(a,e,c){return d(this)&&d(a)&&n(this,a,b(e),b(c))||this},u=function(a,e,c){return d(this)&&d(a)&&p(this,a,b(e),b(c))||this},v=function(a,e,c){return d(this)&&d(a)&&q(this,a,b(e),b(c))||this};(function(){this.before=r;this.after=s;this.afterThrowing=t;this.afterFinally=u;this.around=v}).call(h.prototype)})(Function);
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment