Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

License

NotificationsYou must be signed in to change notification settings

raganwald/method-combinators

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tl;dr

This library gives you some handy function combinators you can use to makeMethod Decorators in CoffeeScript (clickhere for examples in JavaScript):

this.before=  (decoration)->    (base)->->decoration.apply(this,arguments)base.apply(this,arguments)this.after=  (decoration)->    (base)->->decoration.call(this,__value__=base.apply(this,arguments))        __value__this.around=  (decoration)->    (base)->      (argv...)->__value__=undefinedcallback==>__value__=base.apply(this, argv)decoration.apply(this, [callback].concat(argv))        __value__this.provided=  (condition)->    (base)->->ifcondition.apply(this,arguments)base.apply(this,arguments)this.excepting=  (condition)->    (base)->->unlesscondition.apply(this,arguments)base.apply(this,arguments)

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)->->ifcurrentUser?.isValid()methodBody.apply(this,arguments)

You use it like this:

classSomeControllerLikeThingshowUserPreferences:mustBeLoggedIn->## ... show user preferences#

And now, whenevershowUserPreferences is called, nothing happens unlesscurrentUser?.isValid() is truthy. And you can reusemustBeLoggedIn wherever you like. Since method decorators are based on function combinators, they compose very nicely, you can write:

triggersMenuRedraw= (methodBody)->->__rval__=methodBody.apply(this,arguments)@trigger('menu:redraww')                        __rval__classAnotherControllerLikeThingupdateUserPreferences:    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:

  1. You want to do somethingbefore the method's base logic is executed.
  2. You want to do somethingafter the method's base logic is executed.
  3. You want to wrap some logicaround the method's base logic.
  4. You only want to execute the method's base logicprovided some condition is truthy.

Methodcombinators make these common kinds of method decorators extremely easy to write. Instead of:

mustBeLoggedIn= (methodBody)->->ifcurrentUser?.isValid()methodBody.apply(this,arguments)triggersMenuRedraw= (methodBody)->->__rval__=methodBody.apply(this,arguments)@trigger('menu:redraww')                        __rval__

We write:

mustBeLoggedIn=provided->currentUser?.isValid()triggersMenuRedraw=after->@trigger('menu:redraww')

And they work exactly as we expect:

classAnotherControllerLikeThingupdateUserPreferences:    mustBeLoggedIn \    triggersMenuRedraw \->## ... save updated user preferences#

The combinators do the rest!

Can I use this with Node's callback-oriented programming?

This library also providesmethod combinators that work in an asynchronous world.

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. Thebefore andafter decorators don't act as filters. Useprovided if that's what you want.

More specifically:

  • None of the decorators you build with the method combinators change the arguments passed to the method. Thebefore andaround callbacks can execute code before the method body is executed, but only for side-effects.
  • Theprovided decorator will returnvoid 0 if it evaluates to falsy or return whatever the method body returns. There's no other way to change the return value withprovided
  • Thearound decorator will returnvoid 0 if 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.

Is it any good?

Yes.

Can I install it with npm?

Yes:npm install method-combinators

Anything you left out?

Yes, there are some extra combinators that are useful for things like error handling and design-by-contract. Readthe source for yourself. Or have a gander at these blog posts:

I'm writing a book calledCoffeeScript Ristretto. Check it out!

Et cetera

Method Combinators was created byReg "raganwald" Braithwaite. It is available under the terms of theMIT License. Theretry and condition combinators were inspired by Michael Fairley's Rubymethod_decorators.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp