Extended Box with isVisible predicate

Extended Box with isVisible predicate

Signed-off-by: Diwank Singh <a78369447041e6bcf2913d083e4ed301785fc609@gmail.com>

Re: [Letter to a Source-Code-Reader](http://stewd.io/pong/lib/pong.js)

Dear Stewart

Thanks for inspiring me and many like me with the wonders of js.
With all it's warts and issues, JS is still one of my favorite languages.
I think simply by it's virtue of being the language of the web, it surpasses most others
in it's ability to champion the spirit of openness.

I have tried to keep this as simple as possible for the many awesome source code lovers
to read, reuse and critique.

Thanks again for caring to write that letter in 2009. It made a kid smile.

Diwank Singh
July 2013

*****

Browser Bricks
==============

Alright, let's get on with it.

Helper Functions
----------------

First, let's define some helper functions for the application.

    _ =   # _ namespace
      # Extend objects
      extend: (dest, src) ->
        dest[k] = v for own k, v of src
        dest

      # Pick properties
      pick: (obj, props) ->
        result = {}
        result[k] = obj[k] for k in props when obj[k]?

        result

      # UUID function (Copied shamelessly from https://gist.github.com/bmc/1893440)
      uuid: ->
        'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) ->
          r = Math.random() * 16 | 0
          v = if c is 'x' then r else (r & 0x3|0x8)
          v.toString(16)
        )

      # Simple serializer for flat objects
      serialize: (obj, {sep, eq}, cb) ->
        # Exec callback on all values of obj
        obj[k] = cb v for own k, v of obj if cb?

        # Return serialized obj
        ("#{ k }#{ eq }#{ v }" for own k, v of obj).join sep

      # Defer execution of function
      defer: (fn, args...) -> window.setTimeout fn, 1, args...

      # Clone object
      clone: (obj) ->
        # If object extend
        if obj is Object obj
          _.extend {}, obj

        else  # Assume it's array otherwise
          obj.splice 0

Init Function
-------------

Let's write a global init function that can be used to register callbacks which are
executed 'onload'.

    # Callback register
    init = do ->
      # Store registered callbacks
      callbacks = []

      # Run callbacks in order registered
      exec = -> fn?() for fn in callbacks

      # Onload callback
      onLoad = (fn) ->
        window.removeEventListener 'load', init, false
        fn?()

      (cb) ->
        if cb?
          # Register callback
          callbacks.push cb
        else
          # Defer execution until stack cleared
          onLoad -> _.defer exec

        false

    # Attach DOM load listener
    window.addEventListener 'load', init, false

Class: Box
----------

Now, let's define a box that will be the basic building block for the game.
All the objects will inherit from this class.

    class Box
      # -- Private --

      _settings:
        # Default settings
        height: 100
        width:  200
        top:    0
        left:   0

      _props:
        # Fixed window props
        toolbar:     false
        directories: false
        fullscreen:  false
        location:    false
        menubar:     false
        resizable:   false
        scrollbars:  false
        status:      false

      _window: null  # Empty window object
      _url: '/index.html' # Fixed to current page, renders based on context

      _EDITABLE: -> Object.keys @constructor::_settings   # Editable settings

      _update: (settings) ->
        # Update settings
        _.extend @_settings, (_.pick settings, @_EDITABLE())

        # Adjust window props
        @_window?.moveTo?   (@_get 'left'), (@_get 'top')
        @_window?.resizeTo? (@_get 'width'), (@_get 'height')

        # Return a copy of settings
        @_getAll()

      _get: (prop) -> @_settings[prop] if prop in @_EDITABLE()
      _getAll: -> _.extend (_.clone @_settings), @_fixed

      _getDefault: -> @constructor::_settings

      # -- Public --

      constructor: (namespace='', settings) ->
        # Make a copy of default settings
        @_settings = _.clone @_settings

        # Override settings.
        @_update settings

        # Set random name with namespace
        @id = "#{ namespace }#{ if namespace then '-' else '' }#{ _.uuid() }"
        this

      # Show window with settings.
      show: ->
        # Serialize options
        opts = _.serialize @_getAll(), {sep: ',', eq: '='}, (v) ->
          switch v
            when false then 'no'
            when true then 'yes'
            else v+''

        @_window = window.open @_url, @id, opts
        this

      # Hide the window.
      hide: ->
        @_window.close()
        @_window = null
        this

      # Check if window is visible.
      isVisible: -> @_window?.location?

      # Reset window settings.
      reset: ->
        @_update @_getDefault()
        this

      # Return or update window position coords.
      position: (coords...) ->
        # Set new coords
        if coords.length then @_update
          left: coords[0] ? @_getDefault().left  # x
          top:  coords[1] ? @_getDefault().top   # y

        # Return coords
        _.pick @_getAll(), ['top', 'left']

      # Return or update window dimensions.
      size: (dimensions...) ->
        # Set new dimensions
        if dimensions.length then @_update
          width:  dimensions[0] ? @_getDefault().width
          height: dimensions[1] ? @_getDefault().height

        # Return dimensions
        _.pick @_getAll(), ['width', 'height']

Class: Brick (Box)
------------------

Now let's use the class `Box` to design the `Brick` class which
will be used to render the bricks.

It's pretty much a useless box.

    class Brick extends Box
      constructor: (args...) -> super @type(), args...
      type: -> 'brick'

Class: Ball (Box)
-----------------

Alright, so the ball is a little tricky. It has to move two-
dimensionally and bounce off of objects.

So, we need an instance that also stores it's velocity at any
instant and the methods to manipulate it.

    class Ball extends Box
      # -- Private --
      _velocity: [0, 0]

      # Override getDefault to get default velocity
      _getDefault: -> _.extend super(), velocity: _.clone @_velocity

      # -- Public --
      constructor: (args...) ->
        @_velocity = _.clone @_velocity
        super @type(), args...

      type: -> 'ball'

      # Set or retrieve velocity
      velocity: (vel...) ->
        # Set new velocity
        if vel.length then @_velocity = [
          vel[0] ? @_getDefault().velocity[0]         # vx

          # y velocity affects distance from top so inverted to preserve
          # upward positive velocity direction.
          (vel[1] ? @_getDefault().velocity[1]) * -1  # vy
        ]

        # Return velocity
        _.clone @_velocity

Class: Paddle (Ball)
--------------------

A paddle is basically an enlarged ball that's constrained to move in a
straight line.

    class Paddle extends Ball
      type: -> 'paddle'

      # Override velocity to constrain 1D motion
      velocity: (vx) ->
        if vx?
          super vx, @_velocity[1]
        else
          super()

Exports
-------

List of vars exported to global namespace.

    _.extend window ? module.exports ? this,
      _: _
      init: init
      Box: Box
      Brick: Brick
      Ball: Ball
      Paddle: Paddle

Re: [Letter to a Source-Code-Reader](http://stewd.io/pong/lib/pong.js)

Dear Stewart

Thanks for inspiring me and many like me with the wonders of js.
With all it's warts and issues, JS is still one of my favorite languages.
I think simply by it's virtue of being the language of the web, it surpasses most others
in it's ability to champion the spirit of openness.

I have tried to keep this as simple as possible for the many awesome source code lovers
to read, reuse and critique.

Thanks again for caring to write that letter in 2009. It made a kid smile.

Diwank Singh
July 2013

*****

Browser Bricks
==============

Alright, let's get on with it.

Helper Functions
----------------

First, let's define some helper functions for the application.

    _ =   # _ namespace
      # Extend objects
      extend: (dest, src) ->
        dest[k] = v for own k, v of src
        dest

      # Pick properties
      pick: (obj, props) ->
        result = {}
        result[k] = obj[k] for k in props when obj[k]?

        result

      # UUID function (Copied shamelessly from https://gist.github.com/bmc/1893440)
      uuid: ->
        'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) ->
          r = Math.random() * 16 | 0
          v = if c is 'x' then r else (r & 0x3|0x8)
          v.toString(16)
        )

      # Simple serializer for flat objects
      serialize: (obj, {sep, eq}, cb) ->
        # Exec callback on all values of obj
        obj[k] = cb v for own k, v of obj if cb?

        # Return serialized obj
        ("#{ k }#{ eq }#{ v }" for own k, v of obj).join sep

      # Defer execution of function
      defer: (fn, args...) -> window.setTimeout fn, 1, args...

      # Clone object
      clone: (obj) ->
        # If object extend
        if obj is Object obj
          _.extend {}, obj

        else  # Assume it's array otherwise
          obj.splice 0

Init Function
-------------

Let's write a global init function that can be used to register callbacks which are
executed 'onload'.

    # Callback register
    init = do ->
      # Store registered callbacks
      callbacks = []

      # Run callbacks in order registered
      exec = -> fn?() for fn in callbacks

      # Onload callback
      onLoad = (fn) ->
        window.removeEventListener 'load', init, false
        fn?()

      (cb) ->
        if cb?
          # Register callback
          callbacks.push cb
        else
          # Defer execution until stack cleared
          onLoad -> _.defer exec

        false

    # Attach DOM load listener
    window.addEventListener 'load', init, false

Class: Box
----------

Now, let's define a box that will be the basic building block for the game.
All the objects will inherit from this class.

    class Box
      # -- Private --

      _settings:
        # Default settings
        height: 100
        width:  200
        top:    0
        left:   0

      _props:
        # Fixed window props
        toolbar:     false
        directories: false
        fullscreen:  false
        location:    false
        menubar:     false
        resizable:   false
        scrollbars:  false
        status:      false

      _window: null  # Empty window object
      _url: '/index.html' # Fixed to current page, renders based on context

      _EDITABLE: -> Object.keys @constructor::_settings   # Editable settings

      _update: (settings) ->
        # Update settings
        _.extend @_settings, (_.pick settings, @_EDITABLE())

        # Adjust window props
        @_window?.moveTo?   (@_get 'left'), (@_get 'top')
        @_window?.resizeTo? (@_get 'width'), (@_get 'height')

        # Return a copy of settings
        @_getAll()

      _get: (prop) -> @_settings[prop] if prop in @_EDITABLE()
      _getAll: -> _.extend (_.clone @_settings), @_fixed

      _getDefault: -> @constructor::_settings

      # -- Public --

      constructor: (namespace='', settings) ->
        # Make a copy of default settings
        @_settings = _.clone @_settings

        # Override settings.
        @_update settings

        # Set random name with namespace
        @id = "#{ namespace }#{ if namespace then '-' else '' }#{ _.uuid() }"
        this

      # Show window with settings.
      show: ->
        # Serialize options
        opts = _.serialize @_getAll(), {sep: ',', eq: '='}, (v) ->
          switch v
            when false then 'no'
            when true then 'yes'
            else v+''

        @_window = window.open @_url, @id, opts
        this

      # Hide the window.
      hide: ->
        @_window.close()
        @_window = null
        this

      # Reset window settings.
      reset: ->
        @_update @_getDefault()
        this

      # Return or update window position coords.
      position: (coords...) ->
        # Set new coords
        if coords.length then @_update
          left: coords[0] ? @_getDefault().left  # x
          top:  coords[1] ? @_getDefault().top   # y

        # Return coords
        _.pick @_getAll(), ['top', 'left']

      # Return or update window dimensions.
      size: (dimensions...) ->
        # Set new dimensions
        if dimensions.length then @_update
          width:  dimensions[0] ? @_getDefault().width
          height: dimensions[1] ? @_getDefault().height

        # Return dimensions
        _.pick @_getAll(), ['width', 'height']

Class: Brick (Box)
------------------

Now let's use the class `Box` to design the `Brick` class which
will be used to render the bricks.

It's pretty much a useless box.

    class Brick extends Box
      constructor: (args...) -> super @type(), args...
      type: -> 'brick'

Class: Ball (Box)
-----------------

Alright, so the ball is a little tricky. It has to move two-
dimensionally and bounce off of objects.

So, we need an instance that also stores it's velocity at any
instant and the methods to manipulate it.

    class Ball extends Box
      # -- Private --
      _velocity: [0, 0]

      # Override getDefault to get default velocity
      _getDefault: -> _.extend super(), velocity: _.clone @_velocity

      # -- Public --
      constructor: (args...) ->
        @_velocity = _.clone @_velocity
        super @type(), args...

      type: -> 'ball'

      # Set or retrieve velocity
      velocity: (vel...) ->
        # Set new velocity
        if vel.length then @_velocity = [
          vel[0] ? @_getDefault().velocity[0]         # vx

          # y velocity affects distance from top so inverted to preserve
          # upward positive velocity direction.
          (vel[1] ? @_getDefault().velocity[1]) * -1  # vy
        ]

        # Return velocity
        _.clone @_velocity

Class: Paddle (Ball)
--------------------

A paddle is basically an enlarged ball that's constrained to move in a
straight line.

    class Paddle extends Ball
      type: -> 'paddle'

      # Override velocity to constrain 1D motion
      velocity: (vx) ->
        if vx?
          super vx, @_velocity[1]
        else
          super()

Exports
-------

List of vars exported to global namespace.

    _.extend window ? module.exports ? this,
      _: _
      init: init
      Box: Box
      Brick: Brick
      Ball: Ball
      Paddle: Paddle


Fix test loop bug

Fix test loop bug

    {assert} = require 'chai'
    _ = require 'underscore'

Use the global urllite

    urllite = window.urllite

A list of the URL properties we want to verify.

    urlUtilsProps = [
      'protocol'
      'username'
      'password'
      'host'
      'hostname'
      'port'
      'pathname'
      'search'
      'hash'
      'origin'
    ]

A list of URLs to check.

    urls = require './urls.json'

Create an HTML element. We'll use its [decomposed IDL attributes][idl-attributes]
as the canonical parse result to check against.

    a = document.createElement 'a'

    assertParsedEqual = (actual, expected) ->
      assert.deepEqual _.pick(actual, urlUtilsProps...), _.pick(expected, urlUtilsProps...)

    testParsing = (url) ->
      a.href = url
      assertParsedEqual urllite(url), a

    describe 'urllite', ->
      for url in urls
        do (url) ->
          it "should correctly parse #{ url }", -> testParsing url

[idl-attributes]: http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#url-decomposition-idl-attributes

    {assert} = require 'chai'
    _ = require 'underscore'

Use the global urllite

    urllite = window.urllite

A list of the URL properties we want to verify.

    urlUtilsProps = [
      'protocol'
      'username'
      'password'
      'host'
      'hostname'
      'port'
      'pathname'
      'search'
      'hash'
      'origin'
    ]

A list of URLs to check.

    urls = require './urls.json'

Create an HTML element. We'll use its [decomposed IDL attributes][idl-attributes]
as the canonical parse result to check against.

    a = document.createElement 'a'

    assertParsedEqual = (actual, expected) ->
      assert.deepEqual _.pick(actual, urlUtilsProps...), _.pick(expected, urlUtilsProps...)

    testParsing = (url) ->
      a.href = url
      assertParsedEqual urllite(url), a

    describe 'urllite', ->
      for url in urls
        it "should correctly parse #{ url }", -> testParsing url

[idl-attributes]: http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#url-decomposition-idl-attributes


Show and hide the placeholders in the container manager

Container Manager
=================

This manager defines the visibility of the individual display
containers. It is driven chiefly by the display selector.

Like all managers, it is run on a jQuery callback so that it executes
after the DOM has already been loaded.

    $ ->

We bind the selected display's equivalence to the string 'default'
for the visibility of the default container.

        SelectedDisplay.map( (x) -> x is 'default' )
                       .assign $('#default'), 'toggle'

It is left as an exercise to the reader to guess how the rest of these go...

        SelectedDisplay.map( (x) -> x is 'no-entry' )
                       .assign $('#no-entry'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'kill-origin' )
                       .assign $('#kill-origin'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'match-display' )
                       .assign $('#match-display'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'match-sched' )
                       .assign $('#match-sched'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'league-state' )
                       .assign $('#league-state'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'knockout-state' )
                       .assign $('#knockout-state'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'next-match' )
                       .assign $('#next-match'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'day-sched' )
                       .assign $('#day-sched'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'zone' )
                       .assign $('#zone'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'layout' )
                       .assign $('#layout'), 'toggle'
        SelectedDisplay.map( (x) -> x is 'arena-entrance' )
                       .assign $('#arena-entrance'), 'toggle'


Use subject title in measurement instead of subject-source-id.

This job collects data from Sonar for the Sonar keys in the `SubjectSourceIds`
collection.

    class @SonarJob extends Job
      @setupCron: (parser) ->
        parser.recur().every(1).minute()

      handleJob: ->
        for subject_source_id in SubjectSourceIds.find().fetch()
          source = Sources.findOne({_id: subject_source_id.source})
          if source.type != 'sonar'
            continue
          subject = Subjects.findOne({_id: subject_source_id.subject})
          title = "NCLOC " + subject.title
          sonar_key = subject_source_id.title
          try
            result = HTTP.get source.url + 'api/resources?resource=' + sonar_key + '&metrics=true'
            error_message = ''
          catch e
            error_message = e.message
          if result
            json = result.data
            for metric in json[0]['msr']
              if metric['key'] == 'ncloc'
                ncloc = metric['val']
          else
            ncloc = -1
          if error_message != ''
            description = error_message
          else
            description = ncloc + ' LOC'
          insertMeasurement
            projectId: source.projectId
            title: title
            description: description
          console.log(title, description, sonar_key, source.type, source.url, ncloc)

    Job.push new SonarJob

This job collects data from Sonar for the Sonar keys in the `SubjectSourceIds`
collection.

    class @SonarJob extends Job
      @setupCron: (parser) ->
        parser.recur().every(1).minute()

      handleJob: ->
        for subject_source_id in SubjectSourceIds.find().fetch()
          source_id = subject_source_id.source
          source = Sources.findOne({_id: source_id})
          if source.type != 'sonar'
            continue
          sonar_key = subject_source_id.title
          title = "NCLOC " + sonar_key
          try
            result = HTTP.get source.url + 'api/resources?resource=' + sonar_key + '&metrics=true'
            error_message = ''
          catch e
            error_message = e.message
          if result
            json = result.data
            for metric in json[0]['msr']
              if metric['key'] == 'ncloc'
                ncloc = metric['val']
          else
            ncloc = -1
          if error_message != ''
            description = error_message
          else
            description = ncloc + ' LOC'
          insertMeasurement
            projectId: source.projectId
            title: title
            description: description
          console.log(title, description, source.type, source.url, ncloc)

    Job.push new SonarJob


Tweaks for docco gen

Tweaks for docco gen

We always start with the JavaScript-like magic scoping mojo!

    ((root) ->
      root = this
      _ = root._ || require 'underscore'
      F = {}

Non-determinism
---------------

Non-deterministic functions are functions that can have more (or less) than one result.  As known from logic, a binary relation xRy (where x ∈ X, y ∈ Y) can be represented by a *function*  `X -> PowerSet{Y}`. As usual in computer science, we interpret the set `PowerSet{Y}` as a multi-set (realized as a regular scheme list). Compare with SQL, which likewise uses multisets and sequences were sets are properly called for. Also compare with [Wadler's "representing failure as a list of successes."](http://citeseer.uark.edu:8080/citeseerx/showciting;jsessionid=FF5F5EAA9D94B1A8618C49C37451D762?cid=377301).

Thus, we represent a 'relation' (aka `non-deterministic function') as a regular CoffeeScript function that returns an array of possible results.

First, we define two primitive non-deterministic functions; one of them yields no result whatsoever for any argument; the other merely returns its argument as the sole result.

    F.succeed = (result) -> [result]
    F.fail = _.always []

We build more complex non-deterministic functions by combining the existing ones with the help of the following two combinators.

`(disjunction l r)` returns all the results of `l` and all the results of `r`, or returns no results only if neither `l` nor `r` returned any.  In that sense, it is analogous to the logical disjunctionunction.

    disjunction = (l, r) ->
      (x) -> _.cat(l(x), r(x))

`(conjunction l r)` looks like a functional composition of `r` and `l`.  Only `(l x)` may return several results, so we have to apply `r` to each of them.  Obviously `(conjunction fail f)` and `(conjunction f fail)` are both equivalent to `fail`: they return no results, ever. It that sense, `conjunction` is analogous to the logical conjunction.

    conjunction = (l, r) ->
      (x) -> _.mapcat(l(x), r)

JavaScript allows you to pass any number of arguments to a function.  Therefore, we can make a function `disj` that takes any number of arguments and performs a logical disjunction over each.  This makes this version of Sokuza Kanren a bit more flexible in that it allows you to nest any number of relations therein.

    F.disj = () ->
      return F.fail if _.isEmpty(arguments)
      disjunction(_.first(arguments),
	              F.disj.apply(this, _.rest(arguments)))

Likewise, the `conj` function accepts any number of clauses, nit just two as in the original Sokuza.

    F.conj = () ->
      clauses = _.toArray(arguments)
      return F.succeed if _.isEmpty(clauses)
      return _.first(clauses) if _.size(clauses) is 1
      conjunction(_.first(clauses),
                  (s) -> F.conj.apply(null, _.rest(clauses))(s))

And that's all that there is for the built-in non-deterministic functions.

# Knowledge representation
# ------------------------

One may think of regular variables as "certain knowledge": they give  names to definite values.  A logic variable then stands for "improvable ignorance".  An unbound logic variable represents no  knowledge at all; in other words, it represents the result of a measurement *before* we have done the measurement. A logic variable may be associated with a definite value, like 10. That means definite knowledge.  A logic variable may be associated with a semi-definite value, like `[$X]` where `$X` is an unbound variable. We know something about the original variable: it is associated with the array of one element.  We can't say though what that element is. A logic variable can be associated with another, unbound logic variable. In that case, we still don't know what precisely the original variable stands for. However, we can say that it represents the same thing as the other variable. So, our uncertainty is reduced.

I've chosen to represent logic variables with their own simple type.

    class LVar
      constructor: (@name) ->

I've also created a couple of helper functions for creating new variables and checking "variableness" to decouple the representation a bit.

    F.lvar = (name) -> new LVar(name)
    F.isLVar = (v) -> (v instanceof LVar)

I implement associations of logic variables and their values (aka, *bindings*) as a class holding a simple JavaScript object.  One may say that a substitution represents our current knowledge of the world.

    class Bindings
      constructor: (seed = {}) ->
        @binds = _.merge({}, seed)

There are actually two ways of implementing substitutions as associative list. If the variable `$x` is associated with `$y` and `$y` is associated with `1`, we could represent this knowledge as `{$x: 1, $y 1}`. It is easy to lookup the value associated with the variable then, via a simple access. OTH, if we have the binding `{$x:  $y}` and we wish to add the bindings of `$y` to `1`, we have to make rearrangements so to produce `{$x: 1, $y 1}`, or make the traversal on lookup (which we defer to `find` below).

However, if we use an association-list-like structure (arrays of pairs) then we can just record the associations as we learn them, without modifying the previous ones. If originally we knew `[[$x, $y]]` and later we learned that `$y` is associated with `1`, we can simply prepend the latter association, obtaining `[[$y, 1], [$x, $y]]`. So, adding new knowledge becomes fast. The lookup procedure becomes more complex though, as we have to chase the chains of variables. To obtain the value associated with `$x` in the latter substitution, we first lookup `$x`, obtain `$y` (another logic variable), then lookup `$y` finally obtaining `1`.  I prefer the object-representation since it's more idiomatic, but using an a-list provides an intuitively incremental way of representing knowledge: it is easier to backtrack if we later find out our knowledge leads to a contradiction.

      extend: (lvar, value) ->
        o = {}
        o[lvar.name] = value
        new Bindings(_.merge(@binds, o))
      has: (lvar) ->
        @binds.hasOwnProperty(lvar.name)

Find the value associated with `lvar` in the `Bindings` instance.  Return `lvar` itself if it is unbound. In miniKanren, this function is called `walk`.

    lookup: (lvar) ->
        return lvar if !F.isLVar(lvar)
        return this.lookup(@binds[lvar.name]) if this.has(lvar)
        lvar

Starting with an empty binding is akin to saying that we start with zero knowledge.

    F.ignorance = new Bindings()

As mentioned, because we overwrite bindings as we discover them the lookup logic is a little pernicious in the face of logic variables bound to other logic variables.

    find = (v, bindings) ->
      lvar = bindings.lookup(v)
      return lvar if F.isLVar(v)
      if _.isArray(lvar)
        if _.isEmpty(lvar)
          return lvar
        else
          return _.cons(find(_.first(lvar), bindings),
                        find(_.rest(lvar), bindings))
      lvar

# Unification
# -----------

Unification is the process of improving knowledge: or, the process of measurement. That measurement may uncover a contradiction though (things are not what we thought them to be). To be precise, the unification is the statement that two terms are the same. For example, unification of `1` and `1` is successful -- `1` is indeed the same as `1`. That doesn't add however to our knowledge of the world. If the logic variable `$x` is associated with `1` in the current bindings, the unification of `$x` with `2` yields a contradiction (the new measurement is not consistent with the previous measurements / hypotheses). Unification of an unbound logic variable `$x` and `1` improves our knowledge: the "measurement" found that `$x` is actually `1`. We record that fact in the new substitution.

Return the new bindings, or `null` on contradiction:

    F.unify = (l, r, bindings) ->

Find out what `l` actually is given our knowledge contained in `bindings`:

      t1 = bindings.lookup(l)

Find out what `r` actually is given our knowledge contained in `bindings`:

      t2 = bindings.lookup(r)

If `l` and `r` are the same; no new knowledge:

      if _.isEqual(t1, t2)
        return s

`l` is an unbound variable:

      if F.isLVar(t1)
        return bindings.extend(t1, t2)

`r` is an unbound variable:

      if F.isLVar(t2)
        return bindings.extend(t2, t1)

If t1 is a pair, so must be `r`.  This means that I can only unify arrays of nested arrays bottoming out on values or objects.  I cannot unify objects at the moment.

      if _.isArray(t1) && _.isArray(t2)
        s = F.unify(_.first(t1), _.first(t2), bindings)
        s = if (s isnt null) then F.unify(_.rest(t1), _.rest(t2),   bindings) else s
        return s
      return null

# Operational logic
# -----------------

Now we can combine non-deterministic functions (Part 1) and the representation of knowledge (Part 2) into a logic system.  We introduce a `goal` -- a non-deterministic function that takes a substitution and produces 0, 1 or more other bindings (new knowledge). In case the goal produces 0 bindings, we say that the goal failed. We will call any result produced by the goal an "outcome".

The functions `succeed` and `fail` defined earlier are obviously  goals.  The latter is the failing goal. OTH, `succeed` is the trivial successful goal, a tautology that doesn't improve our knowledge of the world. We can now add another primitive goal, the result of a "measurement".  The quantum-mechanical connotations of "the measurement" must be obvious by now.

    F.goal = (l, r) ->
      (bindings) ->
        result = F.unify(l, r, bindings)
        return F.succeed(result) if result isnt null
        return F.fail(bindings)

We also need a way to 'run' a goal, to see what knowledge we can obtain starting from sheer ignorance

    F.run = (goal) ->
      goal(F.ignorance)

# Logic programs
# --------------

We can build more complex goals using lambda-abstractions and previously defined combinators, `conj` and `disj`.  For example, we can define the function `choice` such that `choice(t1, array)` is a goal that succeeds if `t1` is an element of `array`.

    F.choice = ($v, list) ->
      return F.fail if _.isEmpty(list)

      F.disj(F.goal($v, _.first(list)),
                    F.choice($v, _.rest(list)))

The name `choice` should evoke [The Axiom of Choice](http://en.wikipedia.org/wiki/Axiom_of_choice)...

# Exports and sundries
# --------------------

	  if module?
	    module.exports = F
	  else
	    root.F = F

	)(this)


Dynamic directive definition API

Dynamic directive definition API

# Package management for Angular

*This is where shrub's package system meets Angular's module system. Packages'
implementations of controllers, services, filters, providers, and directives
are gathered and registered into Angular.*

    angular.module('shrub.packages', [
      'shrub.directive'
      'shrub.require'
      'shrub.pkgman'
    ])

      .config([
        '$compileProvider', '$controllerProvider', '$filterProvider'
        '$injector', '$provide', 'shrub-directiveProvider'
        'shrub-pkgmanProvider', 'shrub-requireProvider'
        (
          $compileProvider, $controllerProvider, $filterProvider
          $injector, $provide, directive, pkgman, {require}
        ) ->

          config = require 'config'
          debug = require('debug') 'shrub:angular'

#### Invoke hook `shrubAngularController`.

          debug 'Registering controllers...'

          for path, injected of pkgman.invoke 'shrubAngularController'
            controllerName = pkgman.normalizePath path
            debug controllerName
            $controllerProvider.register controllerName, injected

          debug 'Controllers registered.'

          debug 'Registering directives...'

#### Invoke hook `shrubAngularDirective`.

          for path, injected of pkgman.invoke 'shrubAngularDirective'
            directive.define path, injected

          debug 'Directives registered.'

          debug 'Registering filters...'

#### Invoke hook `shrubAngularFilter`.

          for path, injected of pkgman.invoke 'shrubAngularFilter'
            filterName = pkgman.normalizePath path
            debug filterName
            $filterProvider.register filterName, injected

          debug 'Filters registered.'

#### Invoke hook `shrubAngularProvider`.

          debug 'Registering providers...'

          for path, provider of pkgman.invoke 'shrubAngularProvider'
            debug path
            $provide.provider path, provider

          debug 'Providers registered.'

#### Invoke hook `shrubAngularService`.

          debug 'Registering services...'

          for path, injected of pkgman.invoke 'shrubAngularService'
            debug path
            $provide.service path, injected

          debug 'Services registered.'

      ])

      .run([
        '$injector', 'shrub-require'
        ($injector, require) ->

Set an injector so that Angular injection can occur out of band.

          angular_ = require 'angular'
          angular_.setInjector $injector

      ])

Provide Shrub's directive definition API.

    angular.module('shrub.directive', [
      'shrub.pkgman'
      'shrub.require'
    ])

      .provider 'shrub-directive', [
        '$compileProvider', '$injector', '$provide', 'shrub-pkgmanProvider'
        'shrub-requireProvider'
        ($compileProvider, $injector, $provide, pkgman, {require}) ->

          debug = require('debug') 'shrub:angular'

Normalize, augment, and register a directive.

          prepareDirective = (name, path, injected) -> ($injector) ->

Normalize the directive to Directive Definition Object form.

            directive = $injector.invoke injected
            directive = link: directive if angular.isFunction directive

Ensure a compilation function exists for the directive which by default
returns the `link` function.

            directive.compile ?= -> directive.link

Proxy any defined link function, firing any attached any controllers' `link`
method, as well as passing execution on to the original `link` function.

            link = directive.link
            directive.link = (scope, element, attrs, controllers) ->
              if controllers?
                controllers = [controllers] unless angular.isArray controllers
                controller.link? arguments... for controller in controllers

              link? arguments...

Ensure the directive has a name. Defaults to the normalized path of the
implementing package.

            directive.name ?= name

If controller binding is specified, the controller defaults to the directive
name. In other words, if you define a directive and a controller in the same
package, and specify `directive.bindToController = true`, your directive will
include the controller automatically.

            if directive.bindToController
              directive.controller ?= directive.name

Handle a bunch of internal Angular normalization.

            directive.require ?= directive.controller and directive.name
            directive.priority ?= 0
            directive.restrict ?= 'EA'

            if angular.isObject directive.scope
              directive.$$isolateBindings = isolateBindingsFor directive

#### Invoke hook `shrubAngularDirectiveAlter`.

            for injectedDirective in pkgman.invokeFlat(
              'shrubAngularDirectiveAlter', directive, path
            )
              $injector.invoke injectedDirective

Haven't gone deep enough into Angular to understand why this has to be, but it
does.

            directive.index = 0
            return [directive]

Internal Angular state that we have to reset.

          isolateBindingsFor = (directive) ->

            LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/

            bindings = {}

            for scopeName, definition of directive.scope
              match = definition.match LOCAL_REGEXP

              throw angular.$$minErr('$compile')(
                'iscp'
                "
                  Invalid isolate scope definition for directive '{0}'.
                  Definition: {... {1}: '{2}' ...}
                "
                directive.name, scopeName, definition
              ) unless match

              bindings[scopeName] =
                mode: match[1][0]
                collection: match[2] is '*'
                optional: match[3] is '?'
                attrName: match[4] or scopeName

            return bindings

          directive = {}

          directive.define = (path, injected) ->
            directiveName = pkgman.normalizePath path
            debug directiveName

First, register it through Angular's normal registration mechanism. This sets
a bunch of internal state we don't have access to.

            $compileProvider.directive directiveName, injected

Follow that by normalizing, augmenting, and registering the directive again.
It will run over the previous definition, ensuring everything works nicely.

            $provide.factory "#{directiveName}Directive", [
              '$injector', prepareDirective directiveName, path, injected
            ]

          directive.$get = -> directive

          return directive

      ]

Provide Angular with access to Shrub's package manager.

    angular.module('shrub.pkgman', [
      'shrub.require'
    ])

      .provider 'shrub-pkgman', [
        '$provide', 'shrub-requireProvider'
        ($provide, {require}) ->

          config = require 'config'
          debug = require('debug') 'shrub:pkgman'
          pkgman = require 'pkgman'

          debug 'Loading packages...'

Load the package list from configuration.

          pkgman.registerPackageList config.get 'packageList'

          debug 'Packages loaded.'

Simply pass along pkgman as the 'service'.

          pkgman.$get = -> pkgman

          return pkgman
      ]

# Package management for Angular

*This is where shrub's package system meets Angular's module system. Packages'
implementations of controllers, services, filters, providers, and directives
are gathered and registered into Angular.*

    angular.module('shrub.packages', [
      'shrub.require'
      'shrub.pkgman'
    ])

      .config([
        '$compileProvider', '$controllerProvider', '$filterProvider'
        '$injector', '$provide', 'shrub-pkgmanProvider'
        'shrub-requireProvider'
        (
          $compileProvider, $controllerProvider, $filterProvider
          $injector, $provide, pkgman, {require}
        ) ->

          config = require 'config'
          debug = require('debug') 'shrub:angular'

#### Invoke hook `shrubAngularController`.

          debug 'Registering controllers...'

          for path, injected of pkgman.invoke 'shrubAngularController'
            controllerName = pkgman.normalizePath path
            debug controllerName
            $controllerProvider.register controllerName, injected

          debug 'Controllers registered.'

          debug 'Registering directives...'

Normalize, augment, and register a directive.

          prepareDirective = (name, path, injected) -> ($injector) ->

Normalize the directive to Directive Definition Object form.

            directive = $injector.invoke injected
            directive = link: directive if angular.isFunction directive

Ensure a compilation function exists for the directive which by default
returns the `link` function.

            directive.compile ?= -> directive.link

Proxy any defined link function, firing any attached any controllers' `link`
method, as well as passing execution on to the original `link` function.

            link = directive.link
            directive.link = (scope, element, attrs, controllers) ->
              if controllers?
                controllers = [controllers] unless angular.isArray controllers
                controller.link? arguments... for controller in controllers

              link? arguments...

Ensure the directive has a name. Defaults to the normalized path of the
implementing package.

            directive.name ?= name

If controller binding is specified, the controller defaults to the directive
name. In other words, if you define a directive and a controller in the same
package, and specify `directive.bindToController = true`, your directive will
include the controller automatically.

            if directive.bindToController
              directive.controller ?= directive.name

Handle a bunch of internal Angular normalization.

            directive.require ?= directive.controller and directive.name
            directive.priority ?= 0
            directive.restrict ?= 'EA'

            if angular.isObject directive.scope
              directive.$$isolateBindings = isolateBindingsFor directive

#### Invoke hook `shrubAngularDirectiveAlter`.

            for injectedDirective in pkgman.invokeFlat(
              'shrubAngularDirectiveAlter', directive, path
            )
              $injector.invoke injectedDirective

Haven't gone deep enough into Angular to understand why this has to be, but it
does.

            directive.index = 0
            return [directive]

Internal Angular state that we have to reset.

          isolateBindingsFor = (directive) ->

            LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/

            bindings = {}

            for scopeName, definition of directive.scope
              match = definition.match LOCAL_REGEXP

              throw angular.$$minErr('$compile')(
                'iscp'
                "
                  Invalid isolate scope definition for directive '{0}'.
                  Definition: {... {1}: '{2}' ...}
                "
                directive.name, scopeName, definition
              ) unless match

              bindings[scopeName] =
                mode: match[1][0]
                collection: match[2] is '*'
                optional: match[3] is '?'
                attrName: match[4] or scopeName

            return bindings

#### Invoke hook `shrubAngularDirective`.

          for path, injected of pkgman.invoke 'shrubAngularDirective'
            do (path, injected) ->
              directiveName = pkgman.normalizePath path
              debug directiveName

First, register it through Angular's normal registration mechanism. This sets
a bunch of internal state we don't have access to.

              $compileProvider.directive directiveName, injected

Follow that by normalizing, augmenting, and registering the directive again.
It will run over the previous definition, ensuring everything works nicely.

              $provide.factory "#{directiveName}Directive", [
                '$injector', prepareDirective directiveName, path, injected
              ]

          debug 'Directives registered.'

          debug 'Registering filters...'

#### Invoke hook `shrubAngularFilter`.

          for path, injected of pkgman.invoke 'shrubAngularFilter'
            filterName = pkgman.normalizePath path
            debug filterName
            $filterProvider.register filterName, injected

          debug 'Filters registered.'

#### Invoke hook `shrubAngularProvider`.

          debug 'Registering providers...'

          for path, provider of pkgman.invoke 'shrubAngularProvider'
            debug path
            $provide.provider path, provider

          debug 'Providers registered.'

#### Invoke hook `shrubAngularService`.

          debug 'Registering services...'

          for path, injected of pkgman.invoke 'shrubAngularService'
            debug path
            $provide.service path, injected

          debug 'Services registered.'

      ])

      .run([
        '$injector', 'shrub-require'
        ($injector, require) ->

Set an injector so that Angular injection can occur out of band.

          angular_ = require 'angular'
          angular_.setInjector $injector

      ])

The module that provides Angular with access to Shrub's package manager.

    angular.module('shrub.pkgman', [
      'shrub.require'
    ])

      .provider 'shrub-pkgman', [
        '$provide', 'shrub-requireProvider'
        ($provide, {require}) ->

          config = require 'config'
          debug = require('debug') 'shrub:pkgman'
          pkgman = require 'pkgman'

          debug 'Loading packages...'

Load the package list from configuration.

          pkgman.registerPackageList config.get 'packageList'

          debug 'Packages loaded.'

Simply pass along pkgman as the 'service'.

          pkgman.$get = -> pkgman

          return pkgman
      ]


See if I can get the litcoffee thing working now.

Libraries
    _ = require 'lodash'
    Promise = require "bluebird"
    policies = require '../config/policies'

    module.exports = (routeActions, req, res) ->
        new Promise (resolve, reject) ->
            require('./getPolicies')()
            .then (actualPolicies) ->
                policyResults = _.flatten _.map routeActions, (action) ->
                        # What I'm doing here is looking for the policies file.
                        # If there is a policy defined for that action, use that, else use the * catch all.
                        tempPolicies = _.flatten [policies[action.controllerName][action.actionName] || policies[action.controllerName]['*'] ]

                        _.map tempPolicies, (policy) ->
                            # This is pretty straightforward; we'll loop up the policy in the hash
                            # table and then return back their result (which can just be a true or false
                            #
                            # We want to make sure this is properly wrapped in promisey stuff, so we can init
                            # an empty promise then run our stuff in the "then". Since our empty promise only
                            # resolves, it won't hit the catch.
                            tempPromise = new Promise (resolve, reject) -> do resolve
                            tempPromise.then -> actualPolicies[policy] req

                Promise.all policyResults
            .then (results) ->
                # Not entirely sure I like this logic, but it's pretty straightforward:
                # I want to allow synchronous or asynchronous policies.  Subsequently, we can
                # either allow the policy to reject if not permitted or to simply return false.
                unless false in results
                  resolve true
                else
                  reject "Not Authorized"

Libraries
    _ = require 'lodash'
    Promise = require "bluebird"
    policies = require '../config/policies'

    module.exports = (routeActions, req, res) ->
        new Promise (resolve, reject) ->
            require('./getPolicies')()

This should give us an object of all the policies attached to the controller
and action.  To make this a bit more dev-friendly, we'll wrap this in an
array, then flatten it.  This way we can make it a nice, linear, one-dimensional
list to loop through, and that way you can write an array of policies or just one
policy for an action.  If that's what you want. I don't wanna tell you how to live
your life.
            .then (actualPolicies) ->
                policyResults = _.flatten _.map routeActions, (action) ->
                        # What I'm doing here is looking for the policies file.
                        # If there is a policy defined for that action, use that, else use the * catch all.
                        tempPolicies = _.flatten [policies[action.controllerName][action.actionName] || policies[action.controllerName]['*'] ]

                        _.map tempPolicies, (policy) ->
                            # This is pretty straightforward; we'll loop up the policy in the hash
                            # table and then return back their result (which can just be a true or false
                            #
                            # We want to make sure this is properly wrapped in promisey stuff, so we can init
                            # an empty promise then run our stuff in the "then". Since our empty promise only
                            # resolves, it won't hit the catch.
                            tempPromise = new Promise (resolve, reject) -> do resolve
                            tempPromise.then -> actualPolicies[policy] req

                Promise.all policyResults
            .then (results) ->
                # Not entirely sure I like this logic, but it's pretty straightforward:
                # I want to allow synchronous or asynchronous policies.  Subsequently, we can
                # either allow the policy to reject if not permitted or to simply return false.
                unless false in results
                  resolve true
                else
                  reject "Not Authorized"


Remove invalid reference to batman.errorsset.html and switch wording a bit

# Batman.Model

For a general explanation of `Batman.Model` and how it works, see [the guide](/docs/models.html).

_Note_: This documentation uses the term _model_ to refer to the class `Model`
or a `Model` subclass, and the term _record_ to refer to one instance of a
model.

## @primaryKey : string

`primaryKey` is a class level configuration option to change which key batman.js uses as the primary key. Change the option using `set`, like so:

    test 'primary key can be set using @set', ->
      class Shop extends Batman.Model
        @set 'primaryKey', 'shop_id'

      equal Shop.get('primaryKey'), 'shop_id'

The `primaryKey` is what batman.js uses to compare instances to see if they represent the same domain-level object: if two records have the same value at the key specified by `primaryKey`, only one will be in the identity map. The key specified by `primaryKey` is also used by the associations system when determining if a record is related to another record, and by the remote storage adapters to generate URLs for records.

_Note_: The default primaryKey is 'id'.

## @storageKey : string

`storageKey` is a class level option which gives the storage adapters something to interpolate into their specific key generation schemes. In the case of `LocalStorage` or `SessionStorage` adapters, the `storageKey` defines what namespace to store this record under in the `localStorage` or `sessionStorage` host objects, and with the case of the `RestStorage` family of adapters, the `storageKey` assists in URL generation. See the documentation for the storage adapter of your choice for more information.

The default `storageKey` is `null`.

## @persist(mechanism : StorageAdapter) : StorageAdapter

`@persist` is how a `Model` subclass is told to persist itself by means of a `StorageAdapter`. `@persist` accepts either a `StorageAdapter` class or instance and will return either the instantiated class or the instance passed to it for further modification.

    test 'models can be told to persist via a storage adapter', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist TestStorageAdapter

      record = new Shop
      ok record.hasStorage()

    test '@persist returns the instantiated storage adapter', ->
      adapter = false
      class Shop extends Batman.Model
        @resourceName: 'shop'
        adapter = @persist TestStorageAdapter

      ok adapter instanceof Batman.StorageAdapter

    test '@persist accepts already instantiated storage adapters', ->
      adapter = new Batman.StorageAdapter
      adapter.someHandyConfigurationOption = true
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist adapter

      record = new Shop
      ok record.hasStorage()

## @encode(keys...[, encoderObject : [Object|Function]])

`@encode` specifies a list of `keys` a model should expect from and send back to a storage adapter, and any transforms to apply to those attributes as they enter and exit the world of batman.js in the optional `encoderObject`.

The `encoderObject` should have an `encode` and/or a `decode` key which point to functions. The functions accept the "raw" data (the batman.js land value in the case of `encode`, and the backend land value in the case of `decode`), and should return the data suitable for the other side of the link. The functions should have the following signatures:

    encoderObject = {
      encode: (value, key, builtJSON, record) ->
      decode: (value, key, incomingJSON, outgoingObject, record) ->
    }

By default these functions are the identity functions. They apply no transformation. The arguments for `encode` functions are as follows:

 + `value` is the client side value of the `key` on the `record`
 + `key` is the key which the `value` is stored under on the `record`. This is useful when passing the same `encoderObject` which needs to pivot on what key is being encoded to different calls to `encode`.
 + `builtJSON` is the object which is modified by each encoder which will eventually be returned by `toJSON`. To send the server the encoded value under a different key than the `key`, modify this object by putting the value under the desired key, and return `undefined`.
 + `record` is the record on which `toJSON` has been called.

For `decode` functions:

 + `value` is the server side value of the `key` which will end up on the `record`.
 + `key` is the key which the `value` is stored under in the incoming JSON.
 + `incomingJSON` is the JSON which is being decoded into the `record`. This can be used to create compound key decoders.
 + `outgoingObject` is the object which is built up by the decoders and then `mixin`'d to the record.
 + `record` is the record on which `fromJSON` has been called.

The `encode` and `decode` keys can also be false to avoid using the default identity function encoder or decoder.

_Note_: `Batman.Model` subclasses have no encoders by default, except for one which automatically decodes the `primaryKey` of the model, which is usually `id`. To get any data into or out of your model, you must white-list the keys you expect from the server or storage attribute.

    test '@encode accepts a list of keys which are used during decoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      json = {name: "Snowdevil", url: "snowdevil.ca"}
      record = new Shop()
      record.fromJSON(json)
      equal record.get('name'), "Snowdevil"

    test '@encode accepts a list of keys which are used during encoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      record = new Shop(name: "Snowdevil", url: "snowdevil.ca")
      deepEqual record.toJSON(), {name: "Snowdevil", url: "snowdevil.ca"}

    test '@encode accepts custom encoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          encode: (name) -> name.toUpperCase()

      record = new Shop(name: "Snowdevil")
      deepEqual record.toJSON(), {name: "SNOWDEVIL"}

    test '@encode accepts custom decoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          decode: (name) -> name.replace('_', ' ')

      record = new Shop()
      record.fromJSON {name: "Snow_devil"}
      equal record.get('name'), "Snow devil"

    test '@encode can be passed an encoderObject with false to prevent the default encoder or decoder', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', {encode: false, decode: (x) -> x}
        @encode 'url'

      record = new Shop()
      record.fromJSON {name: "Snowdevil", url: "snowdevil.ca"}
      equal record.get('name'), 'Snowdevil'
      equal record.get('url'), "snowdevil.ca"
      deepEqual record.toJSON(), {url: "snowdevil.ca"}, 'The name key is absent because of encode: false'

Some more handy examples:

    test '@encode can be used to turn comma separated values into arrays', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (string) -> string.split(', ')
          encode: (array) -> array.join(', ')

      record = new Post()
      record.fromJSON({tags: 'new, hot, cool'})
      deepEqual record.get('tags'), ['new', 'hot', 'cool']
      deepEqual record.toJSON(), {tags: 'new, hot, cool'}

    test '@encode can be used to turn arrays into sets', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (array) -> new Batman.Set(array...)
          encode: (set) -> set.toArray()

      record = new Post()
      record.fromJSON({tags: ['new', 'hot', 'cool']})
      ok record.get('tags') instanceof Batman.Set
      deepEqual record.toJSON(), {tags: ['new', 'hot', 'cool']}

## @validate(keys...[, options : [Object|Function]])

Validations allow a model to be marked as `valid` or `invalid` based on a set of programmatic rules. By validating a model's data before it gets to the server we can provide immediate feedback to the user about what they have entered and forgo waiting on a round trip to the server. `validate` allows the attachment of validations to the model on particular keys, where the validation is either a built in one (invoked by use of options to pass to them) or a custom one (invoked by use of a custom function as the second argument).

_Note_: Validation in batman.js is always asynchronous, despite the fact that none of the validations may use an asynchronous operation to check for validity. This is so that the API is consistent regardless of the validations used.

Built in validators are attached by calling `@validate` with options designating how to calculate the validity of the key:

    test '@validate accepts options to check for validity', ->
      QUnit.expect(0)
      class Post extends Batman.Model
        @resourceName: 'post'
        @validate 'title', 'body', {presence: true}

The built in validation options are listed below:

 + `presence : boolean`: Assert that the string value is existent (not undefined or null) and has length greather than 0.
 + `numeric : true`: Assert that the value is or can be coerced into a number using `parseFloat`.
 + `greaterThan : number`: Assert that the value is greater than the given number.
 + `greaterThanOrEqualTo : number`: Assert that the value is greater than or equal to the given number.
 + `equalTo : number`: Assert that the value is equal to the given number.
 + `lessThan : number`: Assert that the value is less than the given number.
 + `lessThanOrEqualTo : number`: Assert that the value is less than or equal to the given number.
 + `minLength : number`: Assert that the value's `length` property is greater than the given number.
 + `maxLength : number`: Assert that the value's `length` property is less than the given number.
 + `length : number`: Assert that the value's `length` property is exactly the given number.
 + `lengthWithin : [number, number]` or `lengthIn : [number, number]`: Assert that the value's `length` property is within the ranger specified by the given array of two numbers, where the first number is the lower bound and the second number is the upper bound.
 + `inclusion : in : [list, of, acceptable, values]`: Assert that the value is equal to one of the values in an array.
 + `exclusion : in : [list, of, unacceptable, values]`: Assert that the value is not equal to any of the values in an array.

Custom validators should have the signature `(errors, record, key, callback)`. The arguments are as follows:

 + `errors`: an `ErrorsSet` instance which expects to have `add` called on it to add errors to the model
 + `record`: the record being validated
 + `key`: the key to which the validation has been attached
 + `callback`: a function to call once validation has been completed. Calling this function is __mandatory__.

See [`Model::validate`](/docs/api/batman.model.html#prototype_function_validate) for information on how to get a particular record's validity.

## @loaded : Set

The `loaded` set is available on every model class and holds every model instance seen by the system in order to function as an identity map. Successfully loading or saving individual records or batches of records will result in those records being added to the `loaded` set. Destroying instances will remove records from the identity set.

    test 'the loaded set stores all records seen', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @persist TestStorageAdapter
        @encode 'name'

      ok Post.get('loaded') instanceof Batman.Set
      equal Post.get('loaded.length'), 0
      post = new Post()
      post.save()
      equal Post.get('loaded.length'), 1

    test 'the loaded adds new records caused by loads and removes records caused by destroys', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      post = false
      Post.find(1, (err, result) -> post = result)
      post.destroy()
      equal Post.get('loaded.length'), 1

## @all : Set

The `all` set is an alias to the `loaded` set but with an added implicit `load` on the model. `Model.get('all')` will synchronously return the `loaded` set and asynchronously call `Model.load()` without options to load a batch of records and populate the set originally returned (the `loaded` set) with the records returned by the server.

_Note_: The notion of "all the records" is relative only to the client. It completely depends on the storage adapter in use and any backends which they may contact to determine what comes back during a `Model.load`. This means that if for example your API paginates records, the set found in `all` may hold on the first 50 records instead of the entire backend set.

`all` is useful for listing every instance of a model in a view, and since the `loaded` set will change when the `load` returns, it can be safely bound to.

    asyncTest 'the all set asynchronously fetches records when gotten', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new AsyncTestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      equal Post.get('all.length'), 0, "The synchronously returned set is empty"
      delay ->
        equal Post.get('all.length'), 2, "After the async load the set is populated"

## @clear() : Set

`Model.clear()` empties that `Model`'s identity map. This is useful for tests and other unnatural situations where records new to the system are guaranteed to be as such.

    test 'clearing a model removes all records from the identity map', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}
      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      Post.clear()
      equal Post.get('loaded.length'), 0, "After clear() the loaded set is empty"

## @find(id, callback : Function) : Model

`Model.find()` retrieves a record with the specified `id` from the storage adapter and calls back with an error if one occurred and the record if the operation was successful. `find` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what type of errors may return and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments: an error, and the record asked for. `find` returns an "unloaded" record which, following the load completion, will be populated with the data from the storage adapter.

_Note_: `find` gives two results to calling code: one immediately, and one later. `find` returns a record synchronously as it is called and calls back with a record, and importantly these two records are __not__ guaranteed to be the same instance. This is because batman.js maps the identities of incoming and outgoing records such that there is only ever one canonical instance representing a record, which is useful so bindings are always bound to the same thing. In practice, this means that calling code should use the record `find` calls back with if anything is going to bind to that object, which is most of the time. The returned record however remains useful for state inspection and bookkeeping.

    asyncTest '@find calls back the requested model if no error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter,
          storage:
            'posts2': {name: "Two", id:2}

      post = Post.find 2, (err, result) ->
        throw err if err
        post = result
      equal post.get('name'), undefined
      delay ->
        equal post.get('name'), "Two"

_Note_: `find` must be passed a callback function. This is for two reasons: calling code must be aware that `find`'s return value is not necessarily the canonical instance, and calling code must be able to handle errors.

    asyncTest '@find calls back with the error if an error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter

      error = false
      post = Post.find 3, (err, result) ->
        error = err
      delay ->
        ok error instanceof Error

## @load(options = {}, callback : Function)

`Model.load()` retrieves an array of records according to the given `options` from the storage adapter and calls back with an error if one occurred and the set of records if the operation was successful. `load` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what the options do, what kind of errors may arise, and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments, an error, and the array of records. `load` returns undefined.

For the two main `StorageAdapter`s batman.js provides, the `options` do different things:

- For `Batman.LocalStorage`, `options` act as a filter. The adapter will scan all the records in `localStorage` and return only those records which match all the key/value pairs given in the options.
- For `Batman.RestStorage`, `options` are serialized into query parameters on the `GET` request.

It accepts a callback with two arguments: any error that occurred, and an array of loaded records.

    asyncTest '@load calls back an array of records retrieved from the storage adapter', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter,
          storage:
            'posts1': {name: "One", id:1}
            'posts2': {name: "Two", id:2}

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 2
        equal posts[0].get('name'), "One"

    asyncTest '@load calls back with an empty array if no records are found', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter, storage: []

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 0

## @create(attributes = {}, callback) : Model

## @findOrCreate(attributes = {}, callback) : Model

## id : value

## dirtyKeys : Set

## ::%errors : Batman.ErrorsSet

`errors` is a `Batman.ErrorsSet`, which is simply a `Batman.Set` of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s present on the model instance.

- `user.get('errors')` returns the errors on the `user` record
- `user.get('errors.length')` returns the number of errors, total

You can also access the errors for a specific attribute of the record:

- `user.get('errors.email_address')` returns the errors on the `email_address` attribute
- `user.get('errors.email_address.length')` returns the number of errors on the `email_address` attribute

## constructor(idOrAttributes = {}) : Model

## isNew() : boolean

## updateAttributes(attributes) : Model

## toString() : string

## toJSON() : Object

## fromJSON() : Model

## toParam() : value

## state() : string

## hasStorage() : boolean

## load(options = {}, callback)

## save(options = {}, callback)

## destroy(options = {}, callback)

## ::validate(callback)

`Model::validate` checks the model against the validations declared in the model definition (with [`Model@validate`](/docs/api/batman.model.html#class_function_validate)). This method accepts a callback with two arguments: any JS error that occured within the validator function, and the set of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s that the input generated.

For example:

    test "validate(callback) will call the callback only after all keys have been validated", ->
      class Product extends Batman.Model
        @validate 'name', 'price', presence: yes

      newProduct = new Product
      newProduct.validate (javascriptError, validationErrors) ->
        throw javascriptError if javascriptError
        equal validationErrors.length, 2
        equal newProduct.get('errors.length'), 2
        equal newProduct.get('errors.name.length'), 1
        equal newProduct.get('errors.price.length'), 1

# Batman.ValidationError

`Batman.ValidationError`s represent a failure for a model's field to to pass validation.
They are usually accessed by getting a model's [errors](/docs/api/batman.model.html#prototype_accessor_errors).

## ::%fullMessage

Returns the human-readable attribute name and the validation message:

    test "ValidationError should humanize attribute in the full message", ->
      error = new Batman.ValidationError("fooBarBaz", "isn't valid")
      equal error.get('fullMessage'), "Foo bar baz isn't valid"

# Batman.Model

For a general explanation of `Batman.Model` and how it works, see [the guide](/docs/models.html).

_Note_: This documentation uses the term _model_ to refer to the class `Model`
or a `Model` subclass, and the term _record_ to refer to one instance of a
model.

## @primaryKey : string

`primaryKey` is a class level configuration option to change which key batman.js uses as the primary key. Change the option using `set`, like so:

    test 'primary key can be set using @set', ->
      class Shop extends Batman.Model
        @set 'primaryKey', 'shop_id'

      equal Shop.get('primaryKey'), 'shop_id'

The `primaryKey` is what batman.js uses to compare instances to see if they represent the same domain-level object: if two records have the same value at the key specified by `primaryKey`, only one will be in the identity map. The key specified by `primaryKey` is also used by the associations system when determining if a record is related to another record, and by the remote storage adapters to generate URLs for records.

_Note_: The default primaryKey is 'id'.

## @storageKey : string

`storageKey` is a class level option which gives the storage adapters something to interpolate into their specific key generation schemes. In the case of `LocalStorage` or `SessionStorage` adapters, the `storageKey` defines what namespace to store this record under in the `localStorage` or `sessionStorage` host objects, and with the case of the `RestStorage` family of adapters, the `storageKey` assists in URL generation. See the documentation for the storage adapter of your choice for more information.

The default `storageKey` is `null`.

## @persist(mechanism : StorageAdapter) : StorageAdapter

`@persist` is how a `Model` subclass is told to persist itself by means of a `StorageAdapter`. `@persist` accepts either a `StorageAdapter` class or instance and will return either the instantiated class or the instance passed to it for further modification.

    test 'models can be told to persist via a storage adapter', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist TestStorageAdapter

      record = new Shop
      ok record.hasStorage()

    test '@persist returns the instantiated storage adapter', ->
      adapter = false
      class Shop extends Batman.Model
        @resourceName: 'shop'
        adapter = @persist TestStorageAdapter

      ok adapter instanceof Batman.StorageAdapter

    test '@persist accepts already instantiated storage adapters', ->
      adapter = new Batman.StorageAdapter
      adapter.someHandyConfigurationOption = true
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @persist adapter

      record = new Shop
      ok record.hasStorage()

## @encode(keys...[, encoderObject : [Object|Function]])

`@encode` specifies a list of `keys` a model should expect from and send back to a storage adapter, and any transforms to apply to those attributes as they enter and exit the world of batman.js in the optional `encoderObject`.

The `encoderObject` should have an `encode` and/or a `decode` key which point to functions. The functions accept the "raw" data (the batman.js land value in the case of `encode`, and the backend land value in the case of `decode`), and should return the data suitable for the other side of the link. The functions should have the following signatures:

    encoderObject = {
      encode: (value, key, builtJSON, record) ->
      decode: (value, key, incomingJSON, outgoingObject, record) ->
    }

By default these functions are the identity functions. They apply no transformation. The arguments for `encode` functions are as follows:

 + `value` is the client side value of the `key` on the `record`
 + `key` is the key which the `value` is stored under on the `record`. This is useful when passing the same `encoderObject` which needs to pivot on what key is being encoded to different calls to `encode`.
 + `builtJSON` is the object which is modified by each encoder which will eventually be returned by `toJSON`. To send the server the encoded value under a different key than the `key`, modify this object by putting the value under the desired key, and return `undefined`.
 + `record` is the record on which `toJSON` has been called.

For `decode` functions:

 + `value` is the server side value of the `key` which will end up on the `record`.
 + `key` is the key which the `value` is stored under in the incoming JSON.
 + `incomingJSON` is the JSON which is being decoded into the `record`. This can be used to create compound key decoders.
 + `outgoingObject` is the object which is built up by the decoders and then `mixin`'d to the record.
 + `record` is the record on which `fromJSON` has been called.

The `encode` and `decode` keys can also be false to avoid using the default identity function encoder or decoder.

_Note_: `Batman.Model` subclasses have no encoders by default, except for one which automatically decodes the `primaryKey` of the model, which is usually `id`. To get any data into or out of your model, you must white-list the keys you expect from the server or storage attribute.

    test '@encode accepts a list of keys which are used during decoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      json = {name: "Snowdevil", url: "snowdevil.ca"}
      record = new Shop()
      record.fromJSON(json)
      equal record.get('name'), "Snowdevil"

    test '@encode accepts a list of keys which are used during encoding', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', 'url', 'email', 'country'

      record = new Shop(name: "Snowdevil", url: "snowdevil.ca")
      deepEqual record.toJSON(), {name: "Snowdevil", url: "snowdevil.ca"}

    test '@encode accepts custom encoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          encode: (name) -> name.toUpperCase()

      record = new Shop(name: "Snowdevil")
      deepEqual record.toJSON(), {name: "SNOWDEVIL"}

    test '@encode accepts custom decoders', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name',
          decode: (name) -> name.replace('_', ' ')

      record = new Shop()
      record.fromJSON {name: "Snow_devil"}
      equal record.get('name'), "Snow devil"

    test '@encode can be passed an encoderObject with false to prevent the default encoder or decoder', ->
      class Shop extends Batman.Model
        @resourceName: 'shop'
        @encode 'name', {encode: false, decode: (x) -> x}
        @encode 'url'

      record = new Shop()
      record.fromJSON {name: "Snowdevil", url: "snowdevil.ca"}
      equal record.get('name'), 'Snowdevil'
      equal record.get('url'), "snowdevil.ca"
      deepEqual record.toJSON(), {url: "snowdevil.ca"}, 'The name key is absent because of encode: false'

Some more handy examples:

    test '@encode can be used to turn comma separated values into arrays', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (string) -> string.split(', ')
          encode: (array) -> array.join(', ')

      record = new Post()
      record.fromJSON({tags: 'new, hot, cool'})
      deepEqual record.get('tags'), ['new', 'hot', 'cool']
      deepEqual record.toJSON(), {tags: 'new, hot, cool'}

    test '@encode can be used to turn arrays into sets', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'tags',
          decode: (array) -> new Batman.Set(array...)
          encode: (set) -> set.toArray()

      record = new Post()
      record.fromJSON({tags: ['new', 'hot', 'cool']})
      ok record.get('tags') instanceof Batman.Set
      deepEqual record.toJSON(), {tags: ['new', 'hot', 'cool']}

## @validate(keys...[, options : [Object|Function]])

Validations allow a model to be marked as `valid` or `invalid` based on a set of programmatic rules. By validating a model's data before it gets to the server we can provide immediate feedback to the user about what they have entered and forgo waiting on a round trip to the server. `validate` allows the attachment of validations to the model on particular keys, where the validation is either a built in one (invoked by use of options to pass to them) or a custom one (invoked by use of a custom function as the second argument).

_Note_: Validation in batman.js is always asynchronous, despite the fact that none of the validations may use an asynchronous operation to check for validity. This is so that the API is consistent regardless of the validations used.

Built in validators are attached by calling `@validate` with options designating how to calculate the validity of the key:

    test '@validate accepts options to check for validity', ->
      QUnit.expect(0)
      class Post extends Batman.Model
        @resourceName: 'post'
        @validate 'title', 'body', {presence: true}

The built in validation options are listed below:

 + `presence : boolean`: Assert that the string value is existent (not undefined or null) and has length greather than 0.
 + `numeric : true`: Assert that the value is or can be coerced into a number using `parseFloat`.
 + `greaterThan : number`: Assert that the value is greater than the given number.
 + `greaterThanOrEqualTo : number`: Assert that the value is greater than or equal to the given number.
 + `equalTo : number`: Assert that the value is equal to the given number.
 + `lessThan : number`: Assert that the value is less than the given number.
 + `lessThanOrEqualTo : number`: Assert that the value is less than or equal to the given number.
 + `minLength : number`: Assert that the value's `length` property is greater than the given number.
 + `maxLength : number`: Assert that the value's `length` property is less than the given number.
 + `length : number`: Assert that the value's `length` property is exactly the given number.
 + `lengthWithin : [number, number]` or `lengthIn : [number, number]`: Assert that the value's `length` property is within the ranger specified by the given array of two numbers, where the first number is the lower bound and the second number is the upper bound.
 + `inclusion : in : [list, of, acceptable, values]`: Assert that the value is equal to one of the values in an array.
 + `exclusion : in : [list, of, unacceptable, values]`: Assert that the value is not equal to any of the values in an array.

Custom validators should have the signature `(errors, record, key, callback)`. The arguments are as follows:

 + `errors`: an `ErrorsSet` instance which expects to have `add` called on it to add errors to the model
 + `record`: the record being validated
 + `key`: the key to which the validation has been attached
 + `callback`: a function to call once validation has been completed. Calling this function is __mandatory__.

See [`Model::validate`](/docs/api/batman.model.html#prototype_function_validate) for information on how to get a particular record's validity.

## @loaded : Set

The `loaded` set is available on every model class and holds every model instance seen by the system in order to function as an identity map. Successfully loading or saving individual records or batches of records will result in those records being added to the `loaded` set. Destroying instances will remove records from the identity set.

    test 'the loaded set stores all records seen', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @persist TestStorageAdapter
        @encode 'name'

      ok Post.get('loaded') instanceof Batman.Set
      equal Post.get('loaded.length'), 0
      post = new Post()
      post.save()
      equal Post.get('loaded.length'), 1

    test 'the loaded adds new records caused by loads and removes records caused by destroys', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      post = false
      Post.find(1, (err, result) -> post = result)
      post.destroy()
      equal Post.get('loaded.length'), 1

## @all : Set

The `all` set is an alias to the `loaded` set but with an added implicit `load` on the model. `Model.get('all')` will synchronously return the `loaded` set and asynchronously call `Model.load()` without options to load a batch of records and populate the set originally returned (the `loaded` set) with the records returned by the server.

_Note_: The notion of "all the records" is relative only to the client. It completely depends on the storage adapter in use and any backends which they may contact to determine what comes back during a `Model.load`. This means that if for example your API paginates records, the set found in `all` may hold on the first 50 records instead of the entire backend set.

`all` is useful for listing every instance of a model in a view, and since the `loaded` set will change when the `load` returns, it can be safely bound to.

    asyncTest 'the all set asynchronously fetches records when gotten', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new AsyncTestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}

      Post.persist(adapter)
      equal Post.get('all.length'), 0, "The synchronously returned set is empty"
      delay ->
        equal Post.get('all.length'), 2, "After the async load the set is populated"

## @clear() : Set

`Model.clear()` empties that `Model`'s identity map. This is useful for tests and other unnatural situations where records new to the system are guaranteed to be as such.

    test 'clearing a model removes all records from the identity map', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'

      adapter = new TestStorageAdapter(Post)
      adapter.storage =
          'posts1': {name: "One", id:1}
          'posts2': {name: "Two", id:2}
      Post.persist(adapter)
      Post.load()
      equal Post.get('loaded.length'), 2
      Post.clear()
      equal Post.get('loaded.length'), 0, "After clear() the loaded set is empty"

## @find(id, callback : Function) : Model

`Model.find()` retrieves a record with the specified `id` from the storage adapter and calls back with an error if one occurred and the record if the operation was successful. `find` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what type of errors may return and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments: an error, and the record asked for. `find` returns an "unloaded" record which, following the load completion, will be populated with the data from the storage adapter.

_Note_: `find` gives two results to calling code: one immediately, and one later. `find` returns a record synchronously as it is called and calls back with a record, and importantly these two records are __not__ guaranteed to be the same instance. This is because batman.js maps the identities of incoming and outgoing records such that there is only ever one canonical instance representing a record, which is useful so bindings are always bound to the same thing. In practice, this means that calling code should use the record `find` calls back with if anything is going to bind to that object, which is most of the time. The returned record however remains useful for state inspection and bookkeeping.

    asyncTest '@find calls back the requested model if no error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter,
          storage:
            'posts2': {name: "Two", id:2}

      post = Post.find 2, (err, result) ->
        throw err if err
        post = result
      equal post.get('name'), undefined
      delay ->
        equal post.get('name'), "Two"

_Note_: `find` must be passed a callback function. This is for two reasons: calling code must be aware that `find`'s return value is not necessarily the canonical instance, and calling code must be able to handle errors.

    asyncTest '@find calls back with the error if an error occurs', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist AsyncTestStorageAdapter

      error = false
      post = Post.find 3, (err, result) ->
        error = err
      delay ->
        ok error instanceof Error

## @load(options = {}, callback : Function)

`Model.load()` retrieves an array of records according to the given `options` from the storage adapter and calls back with an error if one occurred and the set of records if the operation was successful. `load` delegates to the storage adapter the `Model` has been `@persist`ed with, so it is up to the storage adapter's semantics to determine what the options do, what kind of errors may arise, and the timeline on which the callback may be called. The `callback` is a required function which should adopt the node style callback signature which accepts two arguments, an error, and the array of records. `load` returns undefined.

For the two main `StorageAdapter`s batman.js provides, the `options` do different things:

- For `Batman.LocalStorage`, `options` act as a filter. The adapter will scan all the records in `localStorage` and return only those records which match all the key/value pairs given in the options.
- For `Batman.RestStorage`, `options` are serialized into query parameters on the `GET` request.

It takes a callback with two arguments: error and the array of loaded records.

    asyncTest '@load calls back an array of records retrieved from the storage adapter', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter,
          storage:
            'posts1': {name: "One", id:1}
            'posts2': {name: "Two", id:2}

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 2
        equal posts[0].get('name'), "One"

    asyncTest '@load calls back with an empty array if no records are found', ->
      class Post extends Batman.Model
        @resourceName: 'post'
        @encode 'name'
        @persist TestStorageAdapter, storage: []

      posts = false
      Post.load (err, result) ->
        throw err if err
        posts = result

      delay ->
        equal posts.length, 0

## @create(attributes = {}, callback) : Model

## @findOrCreate(attributes = {}, callback) : Model

## id : value

## dirtyKeys : Set

## ::%errors : Batman.ErrorsSet

`errors` contains a [`Batman.ErrorsSet`](/docs/api/batman.errorsset.html) of [`Batman.ValidationError`](/docs/api/batman.validationerror.html)s present on the model instance.

- `user.get('errors')` returns the errors on the `user` record
- `user.get('errors.length')` returns the number of errors, total

You can also access the errors for a specific attribute of the record:

- `user.get('errors.email_address')` returns the errors on the `email_address` attribute
- `user.get('errors.email_address.length')` returns the number of errors on the `email_address` attribute

## constructor(idOrAttributes = {}) : Model

## isNew() : boolean

## updateAttributes(attributes) : Model

## toString() : string

## toJSON() : Object

## fromJSON() : Model

## toParam() : value

## state() : string

## hasStorage() : boolean

## load(options = {}, callback)

## save(options = {}, callback)

## destroy(options = {}, callback)

## ::validate(callback)

`Model::validate` checks the model against the validations declared in the model definition (with [`Model@validate`](/docs/api/batman.model.html#class_function_validate)). This method takes a callback with two arguments: any JavaScript error that occurs and the [`Batman.ErrorsSet`](/docs/api/batman.errorsset.html) resulting from the validation tests.
For example:

    test "validate(callback) will call the callback only after all keys have been validated", ->
      class Product extends Batman.Model
        @validate 'name', 'price', presence: yes

      newProduct = new Product
      newProduct.validate (javascriptError, validationErrors) ->
        throw javascriptError if javascriptError
        equal validationErrors.length, 2
        equal newProduct.get('errors.length'), 2
        equal newProduct.get('errors.name.length'), 1
        equal newProduct.get('errors.price.length'), 1

# Batman.ValidationError

`Batman.ValidationError`s represent a failure to validate a particular field on a model.
They are usually accessed by getting a model's [errors](/docs/api/batman.model.html#prototype_accessor_errors).

## ::%fullMessage

Returns the human-readable attribute name and the validation message:

    test "ValidationError should humanize attribute in the full message", ->
      error = new Batman.ValidationError("fooBarBaz", "isn't valid")
      equal error.get('fullMessage'), "Foo bar baz isn't valid"