Skip to content

Instantly share code, notes, and snippets.

@kenaniah
Created June 15, 2017 23:47
Show Gist options
  • Save kenaniah/451d15f693de8b0f68acd1cad37b1546 to your computer and use it in GitHub Desktop.
Save kenaniah/451d15f693de8b0f68acd1cad37b1546 to your computer and use it in GitHub Desktop.
Versioning
module Versioned
module V0
def method_missing name
puts "#{name} not found".red
end
end
module V1
def foo
puts "foo 1"
end
def baz
puts "baz 1"
end
end
module V4
def foo
puts "foo 4"
end
def bar
puts "bar 4"
end
# Undefine a method for this and all future versions
def self.included mod
mod.send :undef_method, :baz
end
end
module V6
def bar
puts "bar 6"
end
end
# return a custom module for the requested version
def self.Version v
# Determine all available versions
versions = self.constants
.sort
.select { |name| /^V[0-9]+$/ === name } # Only include versioning constants
.map { |name| name.to_s[1..-1].to_i } # Convert to integers for numeric comparison
# Determine the effective version to use
version = versions.reverse.find { |version| version <= v }
# Compile the module (or use existing)
Memoized.memoize version do
parent = self
Module.new do
versions.select{ |version| version <= v}.each do |v|
include parent.const_get(:"V#{v}")
end
end
end
end
end
# Attempt to load different versions
v1 = class One; include Versioned::Version 1; end.new
v2 = class Two; include Versioned::Version 5; end.new
v3 = class Three; include Versioned::Version 7; end.new
puts "V1"
v1.foo
v1.bar
v1.baz
puts v1.class.ancestors.inspect.cyan
puts ""
puts "V2"
v2.foo
v2.bar
v2.baz
puts v2.class.ancestors.inspect.cyan
puts ""
puts "V3"
v3.foo
v3.bar
v3.baz
puts v3.class.ancestors.inspect.cyan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment