Created
May 26, 2011 19:16
-
-
Save nickjs/993833 to your computer and use it in GitHub Desktop.
Use case for extended or something similar.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### | |
# Use case for `extended` or something similar. | |
### | |
# Library Code | |
# mixin helper | |
mixin = (to, object) -> | |
for key, value of object | |
to[key] = value | |
if object.initialize | |
object.initialize.call to | |
# make any object observable | |
Observable = { | |
initialize: -> | |
@_observers = {} | |
_observers: {} | |
observe: (key, callback) -> | |
observers = @_observers[key] ||= [] | |
observers.push callback | |
} | |
# some super class of which all children are observable | |
class ObservableObject | |
mixin @, Observable # make classes observable | |
mixin @::, Observable # make instances observable | |
constructor: -> | |
Observable.initialize.call @ # give this instance its own observer hash | |
# not pictured: also copy applicable prototype observers. see below. | |
# Client Code | |
# It's not feasible to expect every client class to mixin Observable again | |
class User extends ObservableObject | |
@all: [] | |
User.observe 'all', -> | |
# Here, we want to observe a static property. | |
# The problem is the _observers hash will always point to Observable._observers | |
# because of static inheritance. We want to create a new User._observers object, | |
# either by reapplying the mixin (and thereby rerunning the initialize function) | |
# or somehow copying the object instead of the pointer. | |
class Request extends ObservableObject | |
url: '' | |
@::observe 'url', -> | |
# Here, we want to know whenever an instance of Request changes its url. While | |
# registering an observer on every instance in the constructor _will_ do the right | |
# thing, it seems wasteful, messy, and hard to document. Thus we simply want to | |
# register a "prototype observer" on Request.prototype._observers, that will be | |
# copied to each instance (code not demonstrated here). That works as well, the | |
# problem is that because prototype._observers was only created on the original | |
# ObservableObject class, _every_ class' prototype._observers is the same object. | |
# Again, what's needed is a way to rerun the intializer function when a new class | |
# (and therefore a new prototype) get created. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment