Skip to content

Instantly share code, notes, and snippets.

@nickjs
Created May 26, 2011 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickjs/993833 to your computer and use it in GitHub Desktop.
Save nickjs/993833 to your computer and use it in GitHub Desktop.
Use case for extended or something similar.
###
# 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