Skip to content

Instantly share code, notes, and snippets.

@laser
Last active January 3, 2016 19:49
Show Gist options
  • Save laser/8510490 to your computer and use it in GitHub Desktop.
Save laser/8510490 to your computer and use it in GitHub Desktop.
Persisting Calculator
# a fake repository
class Repository
def self.save_calculation(op, n1, n2, result)
puts "just saved #{op}, #{n1}, #{n2}, #{result}"
end
end
# implemented in the controller action, result from the
# calculator operation is passed to the Repository
# app/controllers/calculation.rb
def create
h = ActiveSupport::JSON.decode(request.body)
fx = lambda do |op, mod, repo|
lambda do |x, y|
result = mod.method(op.to_sym).to_proc[x, y]
repo.save_calculation op, x, y, result
result
end
end
@result = fx[h["operation"], StatelessCalculator, Repository][h["x"], h["y"]]
render :calculation_view
end
# implemented in the controller action, result from the
# calculator operation is passed to the Repository
# app/controllers/calculation.rb
def create
h = ActiveSupport::JSON.decode(request.body)
fx = lambda do |op, x, y|
result = StatelessCalculator.send op, x, y
Repository.save_calculation op, x, y, result
result
end
@result = fx[h["operation"], h["x"], h["y"]]
render :calculation_view
end
# app/services/calculation_service.rb
class CalculationService
def initialize(repository)
@repository = repository
end
def calculate(operation, x, y)
result = StatelessCalculator.send operation, x, y
@repository.save_calculation operation, x, y, result
result
end
end
# app/controllers/calculation.rb
def create
h = ActiveSupport::JSON.decode(request.body)
@result = MyApp::Services.calculation.calculate h["operation"], h["x"], h["y"]
render :calculation_view
end
# a decorator for the StatelessCalculator, wrapping each method
# with some code to pass results to the injected repository
# app/decorators/calculator.rb
class StatelessCalculatorDecorator
def initialize(calculator, repository)
@calculator = calculator
@repository = repository
end
def method_missing(m, *args, &block)
return super unless [:add, :sub, :mul, :div].include? m
result = @calculator.send m.to_s, *args
@repository.save_calculation m, *args[0], *args[1], result
result
end
end
# app/controllers/calculation.rb
def create
h = ActiveSupport::JSON.decode(request.body)
c = StatelessCalculatorDecorator.new(StatelessCalculator, Repository)
@result = c.send h["operation"], h["x"], h["y"]
render :calculation_view
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment