Last active
December 31, 2015 07:49
-
-
Save jemc/7956510 to your computer and use it in GitHub Desktop.
A type of module combining distinct from include/extend
This file contains hidden or 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
module HappehTheory | |
module SingleCell | |
def gelatin | |
trait | |
end | |
private | |
def trait(*args) | |
"a flagellum" | |
end | |
end | |
module Fish | |
def pyramid | |
trait | |
end | |
private | |
def trait(*args) | |
"a spine" | |
end | |
end | |
module Amphibian | |
def lick | |
trait | |
end | |
private | |
def trait(*args) | |
"a tongue" | |
end | |
end | |
module Reptile | |
def punch | |
trait | |
end | |
private | |
def trait(*args) | |
"an arm" | |
end | |
end | |
module Insect | |
def peer | |
trait | |
end | |
private | |
def trait(*args) | |
"an eyeball" | |
end | |
end | |
module Bird | |
def dance | |
trait | |
end | |
private | |
def trait(*args) | |
"a foot" | |
end | |
end | |
module Mammal | |
def reproduce | |
trait | |
end | |
private | |
def trait(*args) | |
"a live birth" | |
end | |
end | |
class Human | |
def combine mod | |
singleton_class = (class << self; self; end) | |
@combined_module_context ||= {} | |
# Wrap public methods to set the context variable | |
mod.instance_methods.each do |sym| | |
singleton_class.send :define_method, sym do |*args, &block| | |
saved = @combined_module_context[Thread.current] | |
@combined_module_context[Thread.current] = mod | |
mod.instance_method(sym).bind(self).call(*args, &block) | |
.tap { @combined_module_context[Thread.current] = saved } | |
end | |
end | |
# Wrap private methods to call the right method based on context | |
mod.private_instance_methods.each do |sym| | |
singleton_class.send :define_method, sym do |*args, &block| | |
this_mod = @combined_module_context[Thread.current] | |
raise NoMethodError, "private method ##{sym}" unless this_mod | |
this_mod.instance_method(sym).bind(self).call(*args, &block) | |
end | |
end | |
end | |
def initialize *args | |
yield self | |
end | |
end | |
end | |
include HappehTheory | |
h = Human.new do |d| | |
d.combine SingleCell | |
d.combine Fish | |
d.combine Amphibian | |
d.combine Reptile | |
d.combine Insect | |
d.combine Bird | |
d.combine Mammal | |
end | |
require 'pry' | |
binding.pry |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment