Skip to content

Instantly share code, notes, and snippets.

@scottmessinger
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottmessinger/0ea91f43a4b672a0192f to your computer and use it in GitHub Desktop.
Save scottmessinger/0ea91f43a4b672a0192f to your computer and use it in GitHub Desktop.
Transproc thoughts
# Usage: Setup
module A
extend Transproc::Registry
def self.hi(message)
h[:a_message] = message
end
end
module B
extend Transproc::Registry
def self.hi(message)
h[:b_message] = message
end
end
# Usage
# Create and call a single function
A[:hi, "hi from A"].call({})
# Create stream of functions
fns = A[:hi, "hi from A"] >> B[:hi, "hi from B"]
# Call them
fns.call({})
# =============
# The Best Part
# =============
# With or without Transproc, we can still call these functions like normal:
A.a({})
B.b({})
# =====================================================================
# The core of Transproc. Really, about all that's needed for it to work.
# =====================================================================
module Transproc
# ========================
# Registry (the module we extend in our modules)
# ========================
module Registry
def [](fn, *args)
Function.new(fetch(fn), args: args, name: fn)
end
end
# ========================
# Function (the module that the Registry calls)
# ========================
module Function
# The method that the registry calls when we do
# A[:method, :args]
def initialize(fn, options = {})
@fn = fn
@args = options.fetch(:args, [])
@name = options.fetch(:name, fn)
end
# When we call a single transproc
def call(*value)
fn[*value, *args]
rescue => e
raise MalformedInputError.new(@name, value, e)
end
# To get the >> composition
def compose(other)
Composite.new(self, other)
end
alias_method :+, :compose
alias_method :>>, :compose
end
# ========================
# Composite (the module the Function calls if we use >>)
# ========================
module Composite
def initialize(left, right)
@left = left
@right = right
end
def call(value)
right[left[value]]
end
alias_method :[], :call
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment