How can I find where a method is called within my code?

While using Julia’s multiple dispatch feature I built quite a few methods of the same function.

For example:

function foo(df::DataFrame)
...
end

function foo(x::Float64)
...
end

function foo(d::Dict(Symbol,Vector{Float64}))
...
end

Now I suspect that some of these methods may be obsolete, in the sense that they are no longer called by the main program or any other functions therein.

So I would like to remove the obsolete functions. Suppose, for example, that the first of the three functions above is not called anywhere in my code. How could I find out if that is the case?

On thing I could do would be to search for “foo(” and look at every call to a method of foo and check visually if that is the method I am looking for.

This would be quite time consuming.

I could also refine the search using regular expressions, but that would help only for those function calls that specified the argument types.

Another thing I could do would be to comment the method out and try to run the programs I wrote and see where they crash.

There are several problems with this method.

First, I would have to run several programs, and some of them might take a
long time running before they crash.

Second, the function calls might be scattered through several files and there might be several calls in each file. A crash would only let me identify one function call.

So is there a way to locate all function calls to a specific method of a function throughout my code?

4 Likes

You can try @warn("foo(df::DataFrame) is used here") inside foo(df::DataFrame). It outputs a warning to the REPL, including line number, without stopping the code. Not sure how deep it reports line numbers but it could be worth a try.

Depending on how you want to do it these macros could be helpful.
@__LINE__
@__FILE__

If you code spams the REPL with too much too see the warnings you can also try appending x = @__FILE__ to a file.

Edit: Changed @__line__ to @__LINE__ and @__file__ to @__FILE__ in case somebody doesn’t read the following posts.

1 Like

It looks like @warn is deprecated. But I am using the Logging package and can do something along the lines you suggested. That is very helpful.

I could not use the @__line__ and @__file__ macros:

julia> x = @__line__
ERROR: UndefVarError: @__line__ not defined

Maybe I should be using a package that enables this macro.

Not quite the use case I had in mind when building it, but maybe you find the @trace macro from TraceFuns.jl helpful:

julia> function foo(x::Float64)
         :Float
       end
foo (generic function with 1 method)

julia> using TraceFuns

julia> @trace foo(1.0) foo
0: foo(1.0) -- Method foo(x::Float64) in Main at REPL[6]:1
0: foo(1.0) -> Float
:Float

In any case, it appears the macros mentioned by @Daneel are called @__LINE__ and @__FILE__.

Good to know. It seems my code will need some updates for the latest version of Julia. I have been using Julist 1.7.x.

Thanks for the corrections @bertschi. I had some issues formatting them and didn’t notice my mistake.