Shopify/batman — pull request #354 by jamesmacaulay (2012-03-09 17:25:25+00:00)
Title: wrapAccessor macro

Pseudo-inheritance for accessors. This covers a few different use cases.

If all you want to do is make a new getter or setter while keeping the other accessor functions intact, you can use `@wrapAccessor` in more-or-less the same form as `@accessor`, with or without specific keys:

```coffeescript
class NormalizedThing extends Batman.Object
@wrapAccessor 'name',
set: (_, val) -> @name = val?.capitalize?()
```

If you want to use the existing accessor for the given key in order to wrap its functionality, you can provide a function which gets passed the existing accessor and returns a wrapper object as above:

```coffeescript
class AngryHash extends Batman.Hash
@wrapAccessor (core) ->
get: (key) -> core.get.apply(this, arguments).toUpperCase()
```

The downside here is that you can't use the getter-shorthand of `@accessor`; if you pass `@wrapAccessor` a function, it's interpreted as a wrapper block, not a getter.

Here's a more involved example for a Hash which maintains maintains nested persistent Hash values when objects are stored in it:

```coffeescript
class NestedHash extends Batman.Hash
@wrapAccessor (core) ->
set: (key, val) ->
if Batman.typeOf(val) is 'Object' and not (val instanceof Batman.Hash)
existing = core.get.call(this, key)
if existing instanceof Batman.NestedHash
return existing.replace(val)
else
val = new Batman.NestedHash(val)
core.set.call(this, key, val)
```