Skip to content

Instantly share code, notes, and snippets.

@tonywok
Last active January 19, 2021 10:17
Show Gist options
  • Save tonywok/0b6ae01649240b1d9aa04916c0007f3c to your computer and use it in GitHub Desktop.
Save tonywok/0b6ae01649240b1d9aa04916c0007f3c to your computer and use it in GitHub Desktop.
First Class Commands Ruby Notes
# https://raganwald.com/2016/01/19/command-pattern.html
class State
attr_reader :history, :future
attr_accessor :text
def initialize(text)
@history = []
@future = []
@text = text
end
def undo
undoer = history.pop
redoer = undoer.undo
future.unshift(redoer)
undoer.do
end
def redo
redoer = future.shift
undoer = redoer.undo
history.push(undoer)
redoer.do
end
def replace(replacement, from = 0, to = text.length)
doer = Command.new(self, replacement, from, to)
undoer = doer.undo
history.push(undoer)
@future = []
doer.do
end
end
class Command
attr_reader :state, :replacement, :from, :to
def initialize(state, replacement, from, to)
@state = state
@replacement = replacement
@from = from
@to = to
end
def inspect
"Command<#{replacement}, #{from}, #{to}>"
end
def do
puts "History: #{state.history}"
puts "Future: #{state.future}"
state.text = state.text.slice(0...from) + replacement + state.text.slice(to..)
puts state.text
state
end
def undo
was_replaced = state.text.slice(from...to)
Command.new(state, was_replaced, from, from + replacement.length)
end
end
state = State.new("The quick brown fox jumped over the lazy dog")
puts state.text
state.replace("fast", 4, 9)
state.replace("canine", 40, 43)
state.undo
state.undo
state.redo
state.redo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment