Defining multiple methods for same function within single module: how to export

question

#1

I have a module MyTest which has a function f with two methods. From the REPL, I can define and extend a function f in successive definitions. Now I want to export f in my module so that both methods are exposed when I call using MyTest. Below is the example:

funcs.jl file:

function f(x::Number)
    return x^2
end
## f (generic function with 1 method)

function f(x::Number, p::Integer)
    return x^p
end
## f (generic function with 2 methods)

MyTest.jl file:

module MyTest
include("funcs.jl")
export f
end # module

When I run using MyTest, I get the following error:
WARNING: Method definition #f(Any, typeof(MyTest.f)) in module MyTest overwritten.
What am I missing? Thanks!


#2

I think the name of the module in the file MyTest.jl should be MyTest as the Main module of julia has a Test module already.

And, I copy-pasted your code in funcs.jl file and MyTest.jl file as you did. After writing the files, you should also include the file MyTest.jl file to define the module in REPL and than write using MyTest in the REPL if you are using julia-0.6 or using Main.MyTest if you are using julia-1.0. Than no warnings appear on the console.

Here is what I did.

funcs.jl file

function f(x::Number)
    return x^2
end
## f (generic function with 1 method)

function f(x::Number, p::Integer)
    return x^p
end
## f (generic function with 2 methods)

MyTest.jl file

module MyTest
include("funcs.jl")
export f
end # module

On julia0.6

julia> include("MyTest.jl")
MyTest

julia> using MyTest

julia> f
f (generic function with 2 methods)

julia> f(2)
4

julia> f(2,3)
8

On julia1.0


julia> include("MyTest.jl")
Main.MyTest

julia> using Main.MyTest

julia> f
f (generic function with 2 methods)

julia> f(2)
4

julia> f(2,3)
8

#3

Ah, thanks, yes it should by MyTest (I forgot to change in the code I posted).

Why do I need to include first?


#4

You should be able to do using .MyTest (note the dot before the module name) on Julia 0.6 or 1.0. That will also work even if the module happens to be named Test.


#5

See the error if we do not include it first.

julia> using MyTest
ERROR: ArgumentError: Package MyTest not found in current path:
- Run `Pkg.add("MyTest")` to install the MyTest package.

At this point, the module MyTest could not be found in the load path of julia. Note that in the docs of julia it is written that,

Thus the module MyTest is not an installed package that julia can find by searching in the LOAD_PATH . To use it in the REPL, we must first define it in the REPL by loading the contents of the file MyTest.jl to REPL via the command include("MyTest.jl") and then we can use it via the command using MyTest.


#6

Ah, I see. I typically do push!(LOAD_PATH, "~/path-to-MyTest/"), and this way wasn’t working for me. Is one way preferred?


#7

It worked when I tried. The files funcs.jl and MyTest.jl are in the directory whose absolute path is /home/sari/Desktop/temp. So what I did is as follows

julia> push!(LOAD_PATH, "/home/sari/Desktop/temp")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "/home/sari/Desktop/temp"

julia> using MyTest
[ Info: Recompiling stale cache file /home/sari/.julia/compiled/v1.0/MyTest.ji for MyTest [top-level]

julia> f(2,3)
8

Note that the absolute path must be given explicitly as /home/sari/Desktop/temp. ~/Desktop/temp does not work as shown below.

julia> push!(LOAD_PATH, "~/Desktop/temp")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "~/Desktop/temp"

julia> using MyTest
ERROR: ArgumentError: Package MyTest not found in current path:
- Run `Pkg.add("MyTest")` to install the MyTest package.

#8

Ah, yes this works. My error was in another attempt trying to use named parameters. Thanks!