Skip to content
This repository has been archived by the owner on Oct 19, 2018. It is now read-only.

Anatomy Store

Mitch VanDuyn edited this page Jan 22, 2017 · 2 revisions

State Lives In Stores

Your state of the application lives in Stores which are subclasses of HyperStore.

State is accessed via the state method which is available to class and instance methods.

To read a state called foo you would say state.foo.

To change the value or content of a state you say state.foo!. This is called acting on a state.

For example state.foo! [] would change the value of foo to an empty array.

Saying state.foo! << 12 would then push the value 12 onto the array.

Be careful: state.foo << 12 would also change the array, but there would be no notification to the system that foo hand changed. Always add the exclamation when updating the state's content.

States will be created as you access them, but you can also declare them, this useful for readability and also because the declaration allows for initialization and scoping:

private_state :foo                # create state foo
private_state foo: []             # create foo and initialize to the empty array
private_state foo: -> () { ... }  # initialize foo with the return value of the lambda
private_state :foo, scope: :class # there will only be one foo for the entire class
state_reader :foo                 # create state foo, and create a reader method
state_reader :foo, scope: :class  # the reader method will be a class method

class << self
  private_state :foo              # same as private_state :foo, scope: :class
end

Example:

class Cart < HyperStore
  # Cart.new creates a new cart
  # cart is represented as a hash, items are the keys, qty is the value 

  # business logic such as summing the value of the cart, computing taxes
  # etc will all be kept in Actions
  
  # create reader method for the items, and initialize the hash
  state_reader items: Hash.new { |h, k| h[k] = 0 }

  def add!(item, qty = 1)
    # notice we use items! since we are modifying the hash
    state.items![item] += qty
    item
  end

  def remove!(item, qty = 1)
    state.items![item] -= qty
    # remove any items with zero qty from the cart
    state.items!.delete(item) if state.items[item] < 1 
    item
  end
end

Keep Stores Synchronous and Simple

Consider the cart example above. There is no business logic whatsoever in the Cart store. The cart does not know how sum its own value, compute taxes, or validate if the item added is available. These all should go into Actions

*@barriehadfield Whoops! This is not going to work! Actions can't return values... So what do we do? Add states to the cart such cart_value and taxes and have the Action AddToCart and the item and compute the value and taxes? Seems weird *

Clone this wiki locally