Merge two functions from different modules
This file contains 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
function metamerge(f::Function, modulef::Module, g::Function, moduleg::Module, h::Function) | |
# Generate arrays of Method objects for f, g | |
const fmethods = methods(f, (Any...)) | |
const gmethods = methods(g, (Any...)) | |
# println(gmethods) | |
# Generate arrays of method signatures for f, g. | |
# Note that the 'sig' field of a Method is a tuple of types. | |
const fsigs = [ fmethods[i].sig for i in 1:length(fmethods) ] | |
const gsigs = [ gmethods[i].sig for i in 1:length(gmethods) ] | |
# Loop through elements of fsigs and assign appropriate methods of f to h | |
for (i, sig) in enumerate(fsigs) | |
# println(sig) | |
makemethod(h, f, sig, symbol("$modulef")) | |
end | |
# Loop through elements of fsigs and assign appropriate methods of g to h | |
for (i, sig) in enumerate(gsigs) | |
# println(sig) | |
makemethod(h, g, sig, symbol("$moduleg")) | |
end | |
return h | |
end | |
function makemethod(newf::Function, oldf::Function, argtypes::Tuple, modulename::Symbol) | |
# Note that passing a value such as 'A.f' to makemethod() will drop the module | |
# from the function name. We must therefore add it to the expression passed to | |
# RHS (below): | |
exoldf = Expr(:., modulename, QuoteNode(symbol("$oldf"))) | |
# Expression calling 'newf' | |
LHS = Expr(:call, symbol("$newf")) | |
# Expression calling 'oldf' with proper module prefix | |
RHS = Expr(:call, exoldf) | |
# Adds argument symbols with type annotations to signature of call to 'newf' | |
# Adds just argument symbols to call of 'oldf' | |
for (i, arg) in enumerate(argtypes) | |
push!(LHS.args, Expr(:(::), symbol("x$i"), arg)) | |
push!(RHS.args, symbol("x$i")) | |
end | |
# println(LHS) | |
# println(RHS) | |
# Sets the calls of 'newf' and 'oldf' equal to one another and evaluates. | |
exeq = Expr(:(=), LHS, RHS) | |
@eval($exeq) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment