Writing functions for types defined in another module

I want to have type definitions in one module module1 and then write functions that operate on my type in another module module2 and use these functions and the type in my main script / REPL. But in my current setup I then get MethodError: no method matching f(::mytype) Closest candidates are: f(!Matched::Main.module2.module1.mytype)

Here is the full MWE:

module1.jl

module module1

export mytype

mutable struct mytype
	x::Int
end

end #module

module2.jl

module module2

include("./module1.jl")
using .module1

export f

function f(a::mytype)
	println(a.x)
end

end # module

and finally the test script:

testscript.jl

include("./module1.jl")
include("./module2.jl")
using .module1
using .module2

a = mytype(5)
f(a)

and if I then run julia testscript.jl I get the error message

ERROR: LoadError: MethodError: no method matching f(::mytype)
Closest candidates are:
  f(!Matched::Main.module2.module1.mytype)

which sounds an awful lot like julia thinks, that mytype in the MAIN scope and in the module2 scope are different types. How do I have to setup the includes / using to make it clear, that both are the same thing?

1 Like

I think this is a discussion of a similar question:

1 Like

It is similar, but the accepted answer there has one problem: The accepted solution in that thread is to remove include("./module1") \n using .module1 in the main script and write f(a) = ... instead of f(a::mytype) = ... because there is no mytype inside the scope of module2 now.

But what do I do if I want to explcitely specify the argument type of f to be mytype? It seems, that in that case I definitely have to include module1 somehow in module2.

1 Like

Okay, got it fixed now, though I am still not clear why it works now… So if someone can elaborate on that, it would be greatly appreciated. But here is the current, working setup:

The module1 with the types is unchanged:
module1.jl

module module1

export mytype

mutable struct mytype
	x::Int
end

end #module

In module2 I had to replace include("./module1.jl") \n using .module1 with using ..module1 (why??)

module2.jl

module module2

#include("./module1.jl")
using ..module1

export f

function f(a::mytype)
	println(a.x)
end

end # module

And in the test script I have to make sure that I include module1 before module2

testscript.jl

include("./module1.jl")
include("./module2.jl")
using .module2
using .module1

a = mytype(5)
f(a)
1 Like
using .SomeModule

means “use SomeModule within the current module scope”,

using ..SomeModule

means “use SomeModule within the parent module scope”, etc. (more dots - going more levels up).

The initial issue was because including the same file within two different modules imports the definitions within that file into different namespaces.

5 Likes

Nice, thanks!