# Accessing all definitions in a module

**URL:** <https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936>\
**Category:** General Usage\
**Tags:** question, metaprogramming\
**Created:** [April 20, 2020, 11:18pm UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936 "2020-04-20T23:18:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)\
**Post date:** [April 20, 2020, 11:18pm UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/1 "2020-04-20T23:18:38Z")

</div>

For a program analysis tool I’m working on, I need to know about all available functions. However, the traditional suggestion using `names` does not work for me, with the canonical example happening with `NamedTuples`. The (internal) constructor of a `NamedTuple` is written like

```julia
(::Type{NamedTuple{names,T} where T<:Tuple})(args::Tuple) where names = ....

```

This means that it has no nice “name” that it can be found under; you need to know that there’s a two-argument form of NamedTuple to look it up with. This then means that `names(Base)` doesn’t find it, a common problem to all methods defined with the `(::Type{T})(...)` idiom.

It’s possible to see this on a small example.

```julia
foo() = "hi"
module Testme
       (::typeof(Main.foo))(x::Int)=x
end

using .Testme
foo(2) # returns 2

```

However, if we try to find this definition with `names`, we find:

```julia
> names(Testme)
1-element Array{Symbol,1}:
 :Testme

```

Is there a way to access all methods, regardless if they have a distinct name or not?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 21, 2020, 5:19am UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/2 "2020-04-21T05:19:42Z")

</div>

Functions and types have a `parentmodule`, but I am not sure how that particular method in your example is associated with `Testme`. If anything,

```julia
julia> methodswith(typeof(Main.foo))[1].module
Main

```

which is `parentmodule(foo)` too. Code location here may be irrelevant for the purposes of being in a module.

---

<div class="post-metadata">

**Author:** ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)\
**Post date:** [April 21, 2020, 5:42am UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/3 "2020-04-21T05:42:34Z")

</div>

That’s a good point, this issue isn’t really one that’s linked to modules. Sure, in this example it’s possible to identify the inner `foo` from calling `methods(foo)`, and we can find out about `foo` from `names(module)` (which is why the module comes into it) which handles _most_ of the cases. This is how most of the answers to “how do I find all methods” that I’ve been able to find work. However, this doesn’t solve my actual problem, which is the `NamedTuple` example. If we do `methods(NamedTuple)`, we get

```julia
# 1 method for type constructor:
[1] (::Type{NamedTuple})() in Core at boot.jl:542

```

which is fine, except that’s not the constructor that the `(key=value,...)` sugar turns into. We need to know that it’s actually defined on the type `NamedTuple{names,T} where T<:Tuple where names`, at which point we get

```julia
julia> methods(NamedTuple{(:a,:b),T} where T<:Tuple)
# 3 methods for type constructor:
[1] (::Type{NamedTuple{names,T} where T<:Tuple})(args::Tuple) where names in Core at boot.jl:549
[2] (::Type{NamedTuple{names,T} where T<:Tuple})(nt::NamedTuple) where names in Base at namedtuple.jl:88
[3] (::Type{NamedTuple{names,T} where T<:Tuple})(itr) where names in Base at namedtuple.jl:98

```

`names` doesn’t tell you about the existence of methods defined like this, which is where the problem arises: these constructors don’t appear to _have_ names, and aren’t actually “seen” as constructors per se (since if we look them up with `NamedTuple` nothing shows up). I don’t even really know how to access these programmatically if you’re not given the magic type a priori.

I don’t really care about what module defined the function per se, that was just driven by assuming that whatever mechanism there was would work like `names` does. Something that just gave me a big list of all method definitions currently loaded would be fantastic, but I don’t know if that’s possible.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 21, 2020, 6:12am UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/4 "2020-04-21T06:12:20Z")

</div>

> [@ckfinite](#):
>
> a big list of all method definitions currently loaded would be fantastic, but I don’t know if that’s possible

I would try something like

```julia
methodswith(Base.Bottom; supertypes = true)

```

---

<div class="post-metadata">

**Author:** ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)\
**Post date:** [April 21, 2020, 6:18am UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/5 "2020-04-21T06:18:30Z")

</div>

Hmm, that’s really promising but doesn’t seem to solve the `NamedTuple` example; could the problem be that it’s seen as a type constructor?

For example,

```julia
example = first(methods(NamedTuple{(:a, :b),T} where T<:Tuple))
println(example in methods(NamedTuple{(:a, :b),T} where T<:Tuple)) # true
println(example in methodswith(Base.Bottom; supertypes = true)) # false

```

Digging into it more, it looks like `methodswith` is using `names` internally (see [here](https://github.com/JuliaLang/julia/blob/master/stdlib/InteractiveUtils/src/InteractiveUtils.jl#L155)), so I don’t think it will address this particular issue.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 21, 2020, 6:47am UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/6 "2020-04-21T06:47:30Z")

</div>

Since

```julia
julia> Base.Bottom <: (NamedTuple{(:a, :b),T} where T<:Tuple)
true

```

I think it is worth opening an issue (but you may want to wait a bit for other suggestions).

I think your use case is a reasonable one and there should be an API for it.

---

<div class="post-metadata">

**Author:** ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)\
**Post date:** [April 27, 2020, 7:54pm UTC](https://discourse.julialang.org/t/accessing-all-definitions-in-a-module/37936/7 "2020-04-27T19:54:57Z")

</div>

As a quick follow up, if you’re interested, I found a way to solve my particular problem, though it’s not a general (or particularly nice) solution. These “magic” unbound functions all live on the `Type` method table (as they’re bound to specific types in the receiver position) and are associated with `Type.body.name.mt`. Julia internally maintains a special reference to this method table for this reason. I haven’t ran into problems with just loading this set of methods into my analysis yet, but we’ll see.
