Skip to content

Instantly share code, notes, and snippets.

@dividedmind
Created September 1, 2015 13:26
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 dividedmind/94354b9cd8cd4084c9c6 to your computer and use it in GitHub Desktop.
Save dividedmind/94354b9cd8cd4084c9c6 to your computer and use it in GitHub Desktop.
Fake multiple inheritance example
class ModBuilder
def initialize path
@path = path
@files = []
end
def build! build_path
puts "building #{self.class.name} in #{build_path}"
build_mod_files!
puts "Files: #{@files}"
@files
end
def add_file name
@files << name
end
end
class FooMod < ModBuilder
def build_mod_files!
puts "build mod files for foo mod"
add_file 'something'
end
end
class BarMod < ModBuilder
def build_mod_files!
puts "build mod files for bar mod"
add_file 'barthing'
end
end
FooMod.new("game/path").build!("build/path")
BarMod.new("game/path").build!("barbuild/path")
class CompositeMod < ModBuilder
def initialize *a
@mods = klasses.map { |k| k.new *a }
end
def build_mod_files!
([self] + @mods).each_cons(2) do |last, mod|
# note this will break stuff if mod does nontrivial init
# and last clobbers its variables
transfer_variables last, mod
mod.build_mod_files!
end
transfer_variables @mods.last, self
end
def transfer_variables from, to
from.instance_variables.each do |var|
to.instance_variable_set var, from.instance_variable_get(var)
end
end
end
def CompositeMod *klasses
Class.new(CompositeMod).tap do |klass|
klass.send(:define_method, :klasses) { klasses }
end
end
FooBarMod = CompositeMod(FooMod, BarMod)
class FooBarExtraMod < CompositeMod(FooMod, BarMod)
def build_mod_files!
super
puts "extra handling for foo bar mod!"
end
end
FooBarMod.new("game/path").build!("foobar/build/path")
FooBarExtraMod.new("game/path").build!("foobar/build/path")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment