Josh Haas's Web Log

coffeescript fun

without comments

I just wrote probably the most ridiculous, and sort of awesome, code of my life to date. 10 points if you can figure out what it does and what the point of it is (and 20 points if you find a bug!)

The code exports two functions, u.bind and u.let (which is syntactic sugar for a special case of u.bind). Here’s an example / test-case of using them:

class Thing
    constructor: ->
        @x = 0
        setInterval =>
            @x += 1
            @get_x_multiplied_by.update_all()
        , 1000
   
    get_x_multiplied_by: u.bind (y) -> @x * y

a = new Thing()

u.let -> document.title = a.get_x_multiplied_by 7



And here’s the code that defines u.bind and u.let:


#u = module.exports
u = {} #for in-browser testing

u.UUID = -> (Date.now()) + 'x' + Math.round(Math.random() *1e18)

_running_bound = null

magic_number = u.UUID()

smish = (thing) ->
    if thing != null and (typeof thing) == 'object'
        if not thing[magic_number]
            thing[magic_number] = u.UUID()
        return thing[magic_number]
    else
        return (typeof thing) + thing

smush = (args...) -> 
    return (smish arg for arg in args).join('')

run_bound = (bound, fn, args) ->
    hash_key = smush args..., this
    if _running_bound
        if not bound.depends_on_me[hash_key]
            bound.depends_on_me[hash_key] = []
        if _running_bound not in bound.depends_on_me[hash_key]
            bound.depends_on_me[hash_key].push _running_bound
            
    old_running_bound = _running_bound
    _running_bound = {bound: bound, args: args, old_this: this}
    
    if bound.results_cache[hash_key] == undefined
        bound.results_cache[hash_key] = fn.apply this, args
        bound.args_cache[hash_key] = {args: args, old_this: this}
    
    _running_bound = old_running_bound
    
    return bound.results_cache[hash_key]
    

u.bind = (fn) ->
    bound = (args...) ->
        val = run_bound.call this, bound, fn, args
        return val
    
    bound.depends_on_me = {}
    bound.results_cache = {}
    bound.args_cache = {}
    
    bound.update = (args...) ->
        hash_key = smush args..., this
        delete bound.results_cache[hash_key]
        delete bound.args_cache[hash_key]
        bound.apply this, args
        
        depends = bound.depends_on_me[hash_key] ? []
        bound.depends_on_me[hash_key] = []
        for depend in depends
            depend.bound.update.apply depend.old_this, depend.args
            
    
    bound.update_all = ->
        for key, {args, old_this} of bound.args_cache
            bound.update.apply old_this, args
    
    return bound


u.let = (fn) ->
    bound = u.bind fn
    bound()



If you paste the code followed by the test case in the “try coffeescript” window of coffeescript.org, you can see it in action (watch the webpage title).

Written by jphaas

October 28th, 2012 at 3:14 am

Posted in Uncategorized