nickfargo/state.js — Issue #1: Implement <owner>.state as a function
Author: nickfargo
Created: 2012-01-11 21:21:04+00:00
State: open
Labels: augmentation

In the `StateController` constructor:

```javascript
// Rewrites for overloaded arguments
// ...

// Assign accessor function
owner[ name ] = function ( expr ) {
return this === owner ?
expr === undefined ? self : self.get( expr )
:
new StateController( this, name, null, self.current().toString() ),
this[ name ]( expr );
};
```

A nascent object, inheriting from a stateful prototype, may make itself stateful simply by calling `state()` in its own context. A new `StateController` will be created on its behalf, which has no states of its own, but will inherit all stateful behavior of the prototype via protostates and `StateProxy` objects.

```javascript
function Hipster () {
this.state();
}
Hipster.prototype.emote = function () { return ":|"; };
State( Hipster.prototype, {
Stoked: {
emote: function () { return ":)"; }
},
Bummed: {
emote: function () { return ":("; }
}
});

( function () {
var	grrl, dood;

// A new `grrl` will inherit the current state of `Hipster.prototype`
grrl = new Hipster;
grrl.emote(); // ":|"

// But she's too awesome for that
grrl.state().change('Stoked');
grrl.emote(); // ":)"

// Later we decide that the mood of a prototypical Hipster is 'Bummed'
Hipster.prototype.state().change('Bummed');

// That doesn't affect our `grrl` ...
grrl.state().toString(); // "Stoked"

// ... although a new `dood` will be appropriately bummed out
dood = new Hipster;
dood.emote(); // ":("

// Now, even hipsters like to cheer up their fellow hipsters
Hipster.prototype.state('Stoked').addMethod( 'cheerUp', function ( fellowHipster ) {
fellowHipster.state().change('Stoked');
return fellowHipster.emote();
};

// Of course this only works if you yourself are already Stoked
dood.cheerUp( grrl ); // undefined
grrl.cheerUp( dood ); // ":)"
dood.state().toString(); // "Stoked"
})();
```