PHP magic uses __get, _set, and __call. These work much like Ruby's missing_method, and it would be nice to use the same kind of 'magic' in coffeescript, which means javascript.
So how do I implement this in javascript? Catching missing method exceptions won't be scalable. I need to find a different path to the same ends. I know that javascript gives me a different way to trap a missing method. Whenever a method or property is not found, the prototype chain is searched. Coffeescript uses this to implement class inheritance. I also know that the missing methods we're looking for will all be on the current controller instance.
If I can just insert the controller object into the prototype chain of each child object, I will get the same result. This is a simple version of technique I'm using in exspresso:
#
# Magic
#
# Dependency injection via prototype.
#
#
# Get all methods and properties in the prototype chain
#
metadata = (klass) ->
chain = []
props = {}
proto = klass:: # starting point in the chain
# Build an inheritance list
until proto is Object::
chain.push proto
proto = Object.getPrototypeOf(proto)
# Reverse list to process overrides in the correct order
for proto in chain.reverse()
if proto isnt Object::
# Build the inherited properties table
for key in Object.getOwnPropertyNames(proto)
props[key] = Object.getOwnPropertyDescriptor(proto, key)
props
magic = (parent, klass, args...) ->
# clone the object with all properties
child = Object.create(parent, metadata(klass))
# call the constructor
klass.apply child, args
child
#
# Main Controller Class
#
class Controller
constructor: ->
@date = new Date()
@user = magic(@, Model, 'Zaphod')
println: (msg) ->
console.log msg
#
#
#
class Model
constructor: (name) ->
@name = name
hello: () ->
@println @name + " " + @date
#
# Create the applications main controller
#
controller = new Controller()
#
# Call the models hello method.
# Missing methods and properties fallback to the controller.
#
controller.user.hello()
(updated: to use google prettify rather than embedded gists. It makes it easier to focus on the code)
No comments:
Post a Comment