this.before =->decorationapplythisargumentsbaseapplythisargumentsthis.after =->decorationcallthis__value__ = baseapplythisarguments__value__this.around =__value__ = undefined= =>__value__ = baseapplythisargvdecorationapplythiscallbackconcatargv__value__this.provided =->if conditionapplythisargumentsbaseapplythisarguments
The library is called "Method Combinators" because these functions are isomorphic to the combinators from Combinatorial Logic.
A method decorator is a function that takes a function as its argument and returns a new function that is to be used as a method body. For example, this is a method decorator:
You use it like this:
showUserPreferences:mustBeLoggedIn ->## ... show user preferences#
And now, whenever
showUserPreferences is called, nothing happens unless
currentUser?.isValid() is truthy. And you can reuse
mustBeLoggedIn wherever you like. Since method decorators are based on function combinators, they compose very nicely, you can write:
=->__rval__ = methodBodyapplythisarguments@trigger'menu:redraww'__rval__updateUserPreferences:mustBeLoggedIn \triggersMenuRedraw \->## ... save updated user preferences#
Method combinators are convenient function combinators for making method decorators. When writing decorators, the same few patterns tend to crop up regularly:
Method combinators make these common kinds of method decorators extremely easy to write. Instead of:
=->if currentUser?isValidmethodBodyapplythisarguments=->__rval__ = methodBodyapplythisarguments@trigger'menu:redraww'__rval__
mustBeLoggedIn = provided -> currentUser?isValidtriggersMenuRedraw = after -> @trigger'menu:redraww'
And they work exactly as we expect:
updateUserPreferences:mustBeLoggedIn \triggersMenuRedraw \->## ... save updated user preferences#
The combinators do the rest!
after decorators don't act as filters. Use
provided if that's what you want.
aroundcallbacks can execute code before the method body is executed, but only for side-effects.
provideddecorator will return
void 0if it evaluates to falsy or return whatever the method body returns. There's no other way to change the return value with
arounddecorator will return
void 0if you don't call the passed callback. Otherwise, it returns whatever the method body would return. You can't change its arguments or the return value. You don't need to pass arguments to the callback. If you do, they will be ignored.
npm install method-combinators
Yes, there are some extra combinators that are useful for things like error handling and design-by-contract. Read the source for yourself. Or have a gander at these blog posts:
Method Combinators was created by Reg "raganwald" Braithwaite. It is available under the terms of the MIT License. The
retry and condition combinators were inspired by Michael Fairley's Ruby method_decorators.