Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@domgetter
Last active August 29, 2015 14:23
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domgetter/c4b75994a0c3e4dfd65e to your computer and use it in GitHub Desktop.
Save domgetter/c4b75994a0c3e4dfd65e to your computer and use it in GitHub Desktop.
Hash#compose
# Since a key-value store is a finite, discrete function, and functions
# can be composed, then Hashes can be composed.
#
# The syntactic sugar for calling lambdas, accessing array values, and
# other objects which have a #[] method allow composition of Hashes
# with all sorts of objects and contexts with the same implementation.
#
# Play with it at https://eval.in/388458
#
class Hash
def compose_with(hash, other)
each_with_object(hash) {|(k,v), h| h[k]=other[self[k]]}
end
def compose(other)
compose_with({}, other)
end
def compose!(other)
compose_with(self, other)
end
end
# A few examples
a = {:name => 2, :email => 7}
b = {7 => "example@web.com", 2 => "John"}
a.compose(b)
#=> {:name => "John", :email => "example@web.com"}
a.compose([*"d".."k"])
#=> {:name=>"f", :email=>"k"}
a = {name: 0, email: 1}
b = ->(i) { i == 0 ? "John" : "my_email@email.com" }
a.compose(b)
#=> {:name=>"John", :email=>"my_email@email.com"}
a = {name: 0, email: 1}
b = "ab"
a.compose(b)
#=> {:name=>"a", :email=>"b"}
a = {name: :a, email: :b}
b = Thread.new do
Thread.current[:a] = "John"
Thread.current[:b] = "my_email@email.com"
sleep
end
sleep 0.1
a.compose(b)
#=> {:name=>"John", :email=>"my_email@email.com"}
b.kill
# Now for some fun
class Hash
def *(other) #idea taken from: http://jhchabran.com/blog/2012/12/09/fun-with-to-proc-and-compositions/
compose(other)
end
end
{:name => 0, :email => 1} * ["name_url", "email_url"] * {"name_url" => "John", "email_url" => "jj@email.com"}
#=> {:name=>"John", :email=>"jj@email.com"}
upcase = ->(str) {str.upcase}
{:name => "John"} * upcase
#=> {:name => "JOHN"}
# Use cases? No idea, but in that lambda example, you could make the lambda hit a database.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment