Skip to content

Instantly share code, notes, and snippets.

@milankinen
Created November 24, 2012 13:56
Show Gist options
  • Save milankinen/4139794 to your computer and use it in GitHub Desktop.
Save milankinen/4139794 to your computer and use it in GitHub Desktop.
Coffeescript aspects
class MyClass
foo: ->
alert "foobar"
bar: ->
alert "barfoo"
@foo()
aspect = (clz, extensions) ->
weaver =
# this does the actual binding
# this is called from extension code
around: (pointcut, advice) ->
prev = null
prev = if clz.prototype then clz.prototype[pointcut] else null
return if not prev
clz.prototype[pointcut] = ->
args = arguments
obj = this
joinPoint =
getTarget: -> obj
retVal: null
getArgs: -> args
getReturnValue: -> @retVal
setReturnValue: (val) -> @retVal = val
# this is called from advice (usually) once
proceed: ->
@setReturnValue prev.apply(obj, @getArgs())
# this line calls the advice code when
# target object method is called
advice.call(weaver, joinPoint)
return joinPoint.getReturnValue()
# bind advices
extensions.apply(weaver)
aspect MyClass, ->
@around 'foo', (jp) ->
alert "BEFORE"
jp.proceed()
alert "AFTER"
a = new MyClass
a.foo()
alert "---"
a.bar()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment