Last active
November 12, 2017 21:54
-
-
Save MaxPleaner/f8332a44b290a6c787a213d5b450ba89 to your computer and use it in GitHub Desktop.
refinement builder class
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 CoreExt; end | |
module CoreExt::RefinementBuilder | |
def build_refinement(class_name, namespace: Object, refines: Object, &blk) | |
const = namespace.const_set class_name, Module.new(&blk) | |
const.instance_methods(false).each do |method_name| | |
orig_method = const.instance_method method_name | |
const.send :define_method, method_name do |*args, **keywords, &blk| | |
if eql?(const) | |
if keywords.empty? | |
orig_method.bind(const).call *args, &blk | |
else | |
orig_method.bind(const).call *args, **keywords, &blk | |
end | |
else | |
if keywords.empty? | |
const.send method_name, *args, &blk | |
else | |
const.send method_name, *args, **keywords, &blk | |
end | |
end | |
end | |
const.send :module_function, method_name | |
const.send(:refine, refines) { include const } | |
end | |
end | |
module_function :build_refinement | |
refine Object do | |
include CoreExt::RefinementBuilder | |
end | |
end |
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
using CoreExt::RefinementBuilder | |
build_refinement "Util" do | |
def a | |
1 | |
end | |
def b | |
a | |
end | |
end | |
# The above definitiomn enables all the following usages: | |
# 1. Use the methods as a refinement | |
# By default they are patched onto Object but this can be changed | |
# by supplying a refines: <class> option to build_refinement. | |
class Foo | |
using Util | |
puts b # => 1 | |
puts a => 1 | |
end | |
# 2. Use the methods statically | |
puts Util.a # => 1 | |
puts Util.b # => 2 | |
# 3. Use as a typical module via include | |
include Util | |
puts b # => 1 | |
puts a # => 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment