59 lines
1.2 KiB
Ruby
59 lines
1.2 KiB
Ruby
|
module Concurrent
|
||
|
|
||
|
# Methods form module A included to a module B, which is already included into class C,
|
||
|
# will not be visible in the C class. If this module is extended to B then A's methods
|
||
|
# are correctly made visible to C.
|
||
|
#
|
||
|
# @example
|
||
|
# module A
|
||
|
# def a
|
||
|
# :a
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# module B1
|
||
|
# end
|
||
|
#
|
||
|
# class C1
|
||
|
# include B1
|
||
|
# end
|
||
|
#
|
||
|
# module B2
|
||
|
# extend Concurrent::ReInclude
|
||
|
# end
|
||
|
#
|
||
|
# class C2
|
||
|
# include B2
|
||
|
# end
|
||
|
#
|
||
|
# B1.send :include, A
|
||
|
# B2.send :include, A
|
||
|
#
|
||
|
# C1.new.respond_to? :a # => false
|
||
|
# C2.new.respond_to? :a # => true
|
||
|
module ReInclude
|
||
|
# @!visibility private
|
||
|
def included(base)
|
||
|
(@re_include_to_bases ||= []) << [:include, base]
|
||
|
super(base)
|
||
|
end
|
||
|
|
||
|
# @!visibility private
|
||
|
def extended(base)
|
||
|
(@re_include_to_bases ||= []) << [:extend, base]
|
||
|
super(base)
|
||
|
end
|
||
|
|
||
|
# @!visibility private
|
||
|
def include(*modules)
|
||
|
result = super(*modules)
|
||
|
modules.reverse.each do |module_being_included|
|
||
|
(@re_include_to_bases ||= []).each do |method, mod|
|
||
|
mod.send method, module_being_included
|
||
|
end
|
||
|
end
|
||
|
result
|
||
|
end
|
||
|
end
|
||
|
end
|