Skip to content

Instantly share code, notes, and snippets.

@mikhailbortnyk
Last active December 15, 2015 07:09
Show Gist options
  • Save mikhailbortnyk/5221631 to your computer and use it in GitHub Desktop.
Save mikhailbortnyk/5221631 to your computer and use it in GitHub Desktop.
ChainMethod extension for Object
class ChainMethod
def initialize(method_name, params = [], callbacks = {})
@method_name = method_name
@params = params
@callbacks = callbacks
end
def call(base_object)
# preparation work
result = base_object
block = @params.pop if @params.last.is_a?(Proc)
# calling before_callback if passed
@callbacks[:before_callback].call(@params, result) if @callbacks[:before_callback].is_a?(Proc)
# main stuff
if @params.nil?
result = result.send(@method_name.to_sym)
elsif block.is_a?(Proc)
result = result.send(@method_name, *@params, &block)
else
result = result.send(@method_name, *@params)
end
# calling after_callback
@callbacks[:after_callback].call(@params, result) if @callbacks[:after_callback].is_a?(Proc)
# returning value
result
end
end
class Object
def chain_methods(chain)
chain.inject(self) { |result, chain_method| chain_method.call(result) }
end
end
callback_proc = Proc.new do |params, result|
puts "params = #{params.inspect}"
puts "result = #{result.inspect}"
end
puts ["a", "b", "c"].chain_methods([
ChainMethod.new("reverse"),
ChainMethod.new("uniq"),
ChainMethod.new("map", [proc{|x| x.upcase}], {:after_callback => callback_proc}),
ChainMethod.new("map", [proc{|x| x.downcase}], {:before_callback => proc{ |params| puts params.inspect}, :after_callback => callback_proc})
]).inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment