Skip to content

Instantly share code, notes, and snippets.

@rsslldnphy
Created December 4, 2012 19:56
Show Gist options
  • Save rsslldnphy/4208022 to your computer and use it in GitHub Desktop.
Save rsslldnphy/4208022 to your computer and use it in GitHub Desktop.
Some ways of piping and composing methods
require 'rspec'
class Object
def peg(&block)
block.call(self)
end
def wend(arg)
Wender.new(self, arg)
end
end
class TestObject
## Approach 1: Pegging
def peg_with_blocks
5.peg{ |x| square(x) }.peg{ |x| double(x) }
end
## Approach 2: Composition
def compose_with_symbols
Cage.compose(self, :square, :double).(5)
end
## Approach 3: Wending
def wend_with_symbols
wend(5).through(:square).and(:double).and_return
end
def square(x)
x * x
end
def double(x)
x + x
end
end
## Approach 1: Pegging
describe "pegging" do
let(:pegger) { TestObject.new }
describe "peg with symbols" do
it 'applies the methods in turn' do
pegger.peg_with_blocks.should eq 50
end
end
end
## Approach 2: Composition
module Cage
def self.compose(obj, *methods)
->(arg) { methods.inject(arg) { |acc, method| obj.send(method, acc) } }
end
end
describe "Cage" do
let(:cage) { TestObject.new }
describe "#compose" do
it 'composes the passed methods' do
cage.compose_with_symbols.should eq 50
end
end
end
## Approach 3: Wending
class Wender
def initialize(initiator, arg)
@initiator = initiator
@arg = arg
end
def through(method)
Wender.new(initiator, initiator.send(method, arg))
end
alias_method :and, :through
def result
arg
end
alias_method :and_return, :result
private
attr_reader :initiator, :arg
end
describe Wender do
let(:wender) { TestObject.new }
describe "#wend" do
it 'wends the arg through the methods' do
wender.wend_with_symbols.should eq 50
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment