If a module import
s multiple other modules, it may not be obvious where a given function came from. For example:
defmodule Aimable do
import Camera
import Gun
def trigger do
shoot # which import brought it in?
end
end
I know there are ways to minimize this kind of confusion: good naming, focused modules, targeted imports like import Gun, only: [:shoot]
, etc.
But if I come across code like this, is there a way to inspect Aimable
and see the origins of the function shoot
?
You can do this directly:
# from inside the module; IO.inspect(&Aimable.shoot/0) reveals nothing
IO.inspect &shoot/0 #=> &Gun.shoot/0
Check this out
Also remember that you cannot have same function names with same arity in two different modules and import them both in another module. This will result in ambiguity error when calling that function.
Another painful way. You can use function_exported?/3.. Specs:
function_exported?(atom | tuple, atom, arity) :: boolean
Returns true if the module is loaded and contains a public function with the given arity, otherwise false.
Examples:
function_exported?(Gun, :shoot, 0) #=> true
function_exported?(Camera, :shoot, 0) #=> false
__ENV__
As I learned on another question, the __ENV__
macros gives access to various environment info, including __ENV__.functions
and __ENV__.macros
.
__ENV__.functions
returns a list of tuples of modules and the list of functions they provide, like:
[{Some.module, [do_stuff: 2]}, {Other.Module, [a_function: 2, a_function: 3]}]
You could visually scan this for shoot
, or write code to search through it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With