Skip to content

Instantly share code, notes, and snippets.

@billdueber
Created May 3, 2019 18:37
Show Gist options
  • Save billdueber/1e9ced9bd9b0d3154ffde19efd6d011b to your computer and use it in GitHub Desktop.
Save billdueber/1e9ced9bd9b0d3154ffde19efd6d011b to your computer and use it in GitHub Desktop.
Model (in some ways) the elixir pipe from ruby. This is an abomination.
class BasicObject
# kwargs always goes in as at least an empty hash, so need to
# special-case it for methods/functions without keyword args
def safe_call(*args, **kwargs)
kwargs.empty? ? self.call(*args) : self.call(*args, **kwargs)
end
# Call the provided callable (or symbol for a method on the current object)
# with the caller as the first argument along with whatever else
# was passed in as subsequent arguments
def pipe_to(procish, *args, **kwargs)
case procish
when ::Proc
procish.safe_call(self, *args, **kwargs)
when ::Method
procish.safe_call(self, *args, **kwargs)
when ::UnboundMethod
procish.bind(self).safe_call(*args, **kwargs)
when ::Symbol
m = self.method(procish)
m.safe_call(*args, **kwargs)
else
raise RuntimeError.new("pipe_to first arg must be a callable or a symbol representing a method on the recieved object")
end
end
end
class Module
# Find a method and return it as a lambda suitable
# for pipe_to
def method_missing(sym, *args, **kwargs, &block)
m = begin
instance_method(sym)
rescue NameError
method(sym)
rescue
raise NameError.new("No such method #{sym}")
end
->(*args, **kwargs) do
m.bind(self).safe_call(*args, **kwargs)
end
end
end
module PureFuctionModule
def hello(name)
"Hello, #{name}"
end
def add_last(greeting, lastname: "ddd")
"#{greeting} #{lastname}"
end
end
puts "Bill"
.pipe_to(PureFuctionModule.hello)
.pipe_to(PureFuctionModule.add_last, lastname: "Dueber")
.pipe_to(->(greeting) { greeting.gsub(/Hello/, "Good evening")})
# => "Good evening, Bill Dueber"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment