Skip to content

Instantly share code, notes, and snippets.

@eadz
Last active October 4, 2022 21:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eadz/31c87375722397be861a0dbcf7fb7408 to your computer and use it in GitHub Desktop.
Save eadz/31c87375722397be861a0dbcf7fb7408 to your computer and use it in GitHub Desktop.
Redux in Ruby
# Redux in Ruby
class Store
attr_reader :state
def initialize(initial_state, *reducers)
@reducers = reducers
@state = initial_state || {}
end
def dispatch(action)
@state = @reducers.reduce(state.dup) do |s, reducer|
reducer.call(s, action)
end
end
end
# Reducers
totals_reducer = ->(state, action) do
case action[:type]
when 'ADD_ITEM' then state[:total] += 1
when 'REMOVE_ITEM' then state[:total] -= 1
end
state
end
items_reducer = -> (state, action) do
case action[:type]
when 'ADD_ITEM' then state[:items] << action[:item]
when 'REMOVE_ITEM' then state[:items] = state[:items] - [action[:item]]
end
state
end
# DEMO
@store = Store.new({ total: 0, items: [] }, items_reducer, totals_reducer)
@store.dispatch type: 'ADD_ITEM', item: 'APPLES'
@store.dispatch type: 'ADD_ITEM', item: 'BANANAS'
@store.dispatch type: 'REMOVE_ITEM', item: 'APPLES'
@store.dispatch type: 'ADD_ITEM', item: 'FEIJOAS'
puts @store.state # => {total: 2, items: ["BANANAS", "FEIJOAS"]}
@lucascaton
Copy link

Super cool, @eadz! 😃

Line 12 might be a good place to use Enumerable#reduce (inject alias) as its name makes more sense in that context? 🙂

@eadz
Copy link
Author

eadz commented Jun 12, 2020

👍

@peterc
Copy link

peterc commented Oct 4, 2022

Oddly enough I just implemented the same thing for a bit of fun and our implementations are extremely similar. A good sign for me, at least :-) One thing that's easy enough to add is a subscribe method and push a passed block onto an array of procs that can be called with the new state at the end of dispatch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment