method-combinators
v1.3.1
Published
Coffeescript/Javascript method combinators
Downloads
3
Readme
method-combinators
tl;dr
This library gives you some handy function combinators you can use to make Method Decorators in CoffeeScript or JavaScript:
before (...) -> something
# => (methodBody) ->
# (argv...) ->
# ((...) -> something).apply(this, argv)
# methodBody.apply(this, argv)
after (...) -> something
# => (methodBody) ->
# (argv...) ->
# __ret__ = methodBody.apply(this, argv)
# ((...) -> something).apply(this, argv)
# __ret__
around (...) -> something
# => (methodBody) ->
# (argv...) ->
# (...) -> something).call(
# this,
# (__ret__ = => methodBody.apply(this, argv)),
# argv...
# )
# __ret__
provided (...) -> something
# => (methodBody) ->
# (argv...) ->
# if ((...) -> something).apply(this, argv)
# methodBody.apply(this, argv)
The library is called "Method Combinators" because these functions are isomorphic to the combinators from Combinatorial Logic.
Back up the truck, Chuck. What's a Method Decorator?
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:
mustBeLoggedIn = (methodBody) ->
(argv...) ->
if currentUser
methodBody.apply(this, argv)
You use it like this:
class SomeControllerLikeThing
showUserPreferences:
mustBeLoggedIn ->
#
# ... show user preferences
#
And now, whenever showUserPreferences
is called, nothing happens unless currentUser
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:
triggersMenuRedraw = (methodBody) ->
(argv...) ->
__rval__ = methodBody.apply(this, argv)
@trigger('menu:redraww')
__rval__
class AnotherControllerLikeThing
updateUserPreferences:
mustBeLoggedIn \
triggersMenuRedraw \
->
#
# ... save updated user preferences
#
Fine. Method Decorators look cool. So what's a Method Combinator?
Method combinators are convenient function combinators for making method decorators. When writing decorators, the same few patterns tend to crop up regularly:
- You want to do something before the method's base logic is executed.
- You want to do something after the method's base logic is executed.
- You want to do wrap some logic around the method's base logic.
- You only want to execute the method's base logic provided some condition is truthy.
Method combinators make these four kinds of method decorators extremely easy to write. Instead of:
mustBeLoggedIn = (methodBody) ->
(argv...) ->
if currentUser
methodBody.apply(this, argv)
triggersMenuRedraw = (methodBody) ->
(argv...) ->
__rval__ = methodBody.apply(this, argv)
@trigger('menu:redraww')
__rval__
We write:
mustBeLoggedIn = provided -> currentUser
triggersMenuRedraw = after -> @trigger('menu:redraww')
The combinators do the rest!
A
So these are like RubyOnRails controller filters?
There are some differences. These are much simpler, which is in keeping with JavaScript's elegant style. For example, in Rails all of the filters can abort the filter chain by returning something falsy. The before
and after
decorators don't act as filters. Use provided
is that's what you want.
Is it any good?
Yes.
Can I use it with pure Javascript?
Yes.
Can I install it with npm?
Yes: `npm install method-combinators
How to get started
Eat a hearty breakfast. Breakfast is the most important meal of the day! :-)
Et cetera
Method Combinators was created by Reg "raganwald" Braithwaite. It is available under the terms of the MIT License.