Created
June 15, 2017 23:47
-
-
Save kenaniah/451d15f693de8b0f68acd1cad37b1546 to your computer and use it in GitHub Desktop.
Versioning
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 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