dfdx
June 5, 2018, 1:46pm
1
module A
foo(???) = println("I've been called from $???")
end
module B
import A
A.foo() # should pring "I've been called from B"
end
Is it possible to get this behavior, i.e. find out the caller’s module without requiring it to explicitly pass @__MODULE__
? I tired:
foo(; mod=@__MODULE__)
But for obvious reasons it returns the module of foo
itself instead of the caller.
julia> module A
function foo()
s = stacktrace()
get(s[2].linfo).def.module
end
end
A
julia> module B
using A
foo() = A.foo()
end
B
julia> B.foo()
B
Obviously needs error handling, probably only works on 0.6, doesn’t quite do what you want (since it needs to be called in a function defined in B
) and is generally bad since it reaches into internals, but that is at least one way to get what you want
3 Likes
dfdx
June 6, 2018, 1:16pm
3
Interesting solution, thanks!
For reference, here’s Julia 0.7 version:
module A
function foo()
s = stacktrace()
s[2].linfo.def.module
end
end
module B
using Main.A
foo() = A.foo()
end
B.foo() # ==> Main.B
1 Like
This does not seem to work for macros, does somebody know how to access this from a macro?
module A
macro foo()
s = stacktrace()
s[end].linfo.def.module
end
end
module B
using Main.A
foo() = A.@foo()
end
B.foo() # WRONG: ==> Main.A
it returns Main.A
instead of Main.B
, is that a bug?
No, that’s just a consequence of the differences between macros and functions. You want
julia> module A
macro foo()
__module__
end
end
Main.A
julia> module B
using Main.A
foo() = A.@foo()
end
Main.B
julia> B.foo()
Main.B
instead. See here for why that works.
2 Likes