Created
May 3, 2019 18:37
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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