Skip to content

Instantly share code, notes, and snippets.

@pithyless
Created April 1, 2012 16:04
Show Gist options
  • Save pithyless/2276640 to your computer and use it in GitHub Desktop.
Save pithyless/2276640 to your computer and use it in GitHub Desktop.
DCI via SimpleDelegator and a hint of metaprogramming
get '/give/me/gazebo/not/gazelle/:min_size' do
pricing = PriceCalculator.new
ParamsExtractor.new(pricing).parse(params)
GazelleFinder.new(pricing).find_all_gazelles
GazelleFilter.new(pricing).remove_sick_gazelles # pricing has access to #gazelles
GazeboBuilder.new(pricing).calculate_size_of_gazebo
GazeboPricer.new(pricing).calculate_final_price # pricing no longer has #gazelles
pricing.response.to_xml
end
class PricingCalculator
attr_accessor :minimum_size # sure, not a great domain example
end
class ParamsExtractor < SimpleDelegator
def initialize(obj)
super
end
# sometimes you just want to work with your data model
def parse(params)
self.minimum_size = params[:min_size]
end
end
class GazelleFinder < SimpleDelegator
def initialize(obj)
super
@obj = obj
end
# sometimes you want to generate "temporary" data for next steps
def find_all_gazelles(params)
(class << @obj; self; end).instance_eval do
define_method(:gazelles) do
[1,2,3]
end
end
end
end
# But by the time we call pricing.response, we want to undef #gazelles,
# because it was just a temporary mutation of our PricingTransaction
# state, and it should not be available after we calculated the price.
@markburns
Copy link

forgive my metaprogramming fu if I'm missing something, but isn't

(class << @obj; self; end).instance_eval do
  define_method(:gazelles) do
    [1,2,3]
  end
end

the same as

def @obj.gazelles do
  [1,2,3]
end

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