Last active
          August 29, 2015 14:08 
        
      - 
      
- 
        Save mattdeboard/b03b25986255eead6c68 to your computer and use it in GitHub Desktop. 
    Super naive impl of a Clojure-style atom in CoffeeScript
  
        
  
    
      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
    
  
  
    
  | class Atom | |
| __state: | |
| initial: null | |
| current: null | |
| constructor: (state) -> | |
| @__state['current'] = state | |
| @__state['initial'] = state | |
| _cloneState: (phase = 'current') -> | |
| ### | |
| Returns a copy of a particular phase (i.e. either current or initial) | |
| of the atom state. | |
| ### | |
| obj = @__state[phase] | |
| if typeof(obj) == 'object' | |
| tmp_obj = {} | |
| for k, v of obj | |
| tmp_obj[k] = v | |
| return tmp_obj | |
| else if typeof(obj) == 'array' | |
| return obj.slice() | |
| else | |
| return obj | |
| _deref: -> | |
| @_cloneState() | |
| _swap: (fn, args...) -> | |
| curr_state = @_deref() | |
| @__state['last'] = curr_state | |
| args.splice 0, 0, curr_state | |
| @__state['current'] = fn.apply(fn, args) | |
| @ | |
| _reset: (new_val = null) -> | |
| new_state = @_cloneState('initial') | |
| if new_val? | |
| new_state = new_val | |
| @__state['current'] = new_state | |
| @ | |
| deref = (atom) -> | |
| ### | |
| Return a copy of the current state of the atom. Modifications to the | |
| value returned will not update the state of the atom. Use 'swap' for | |
| that. | |
| ### | |
| atom._deref() | |
| swap = (atom, fn, args...) -> | |
| ### | |
| Transform the current state of the atom by calling 'fn' with arguments | |
| 'args'. | |
| ### | |
| atom._swap fn, args | |
| reset = (atom, new_val) -> | |
| ### | |
| Set the value of atom without regard to its current value. If | |
| 'new_val' is not provided, then resets value of atom to its | |
| initial value. | |
| ### | |
| atom._reset(new_val) | |
| app_state = new Atom | |
| foo: "bar" | |
| baz: "qux" | |
| ### | |
| Example: | |
| Adds a new key to 'app_state'. | |
| Obviously this requires some knowledge of the shape of the app state in the | |
| atom. | |
| ### | |
| _func_for_swap = (state_val) -> | |
| # 'state_val' will be the value of a dereferenced atom. | |
| state_val['quux'] = 'quuux' | |
| state_val | |
| # Look at the current state | |
| console.log deref(app_state) | |
| # Modify the atom state | |
| swap app_state, _func_for_swap | |
| # Should have 'quux' key now | |
| console.log deref(app_state) | |
| # Set it back to its original value | |
| reset app_state | |
| # Should match initial state | |
| console.log deref(app_state) | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment