How to use an abstract type created in module A in module B

Hi, I created this code in Main:

module PormG

abstract type PormGAbstractType end
abstract type SQLType <: PormGAbstractType end

mutable struct SQLQuery <: SQLType
  model_name::Union{String, Missing}
  ...
end

function myfunction(t::SQLType)
  ...
end

end

When I call the myfunction with a SQLType object, this works

But when I move myfunction to other module

module QueryBuilder

import PormG

function myfunction(t::PormG.SQLType)
  print(t)
end
end

I get this:

ERROR: MethodError: no method matching get_on_query(::Main.PormG.SQLQuery)

Closest candidates are:
  get_on_query(::PormG.SQLType)
   @ Main.PormG C:\Sistemas\PormG\src\QueryBuilder.jl:15

Why does this happen?

You need to provide more information on what call triggered the error and what any of the functions do, especially myfunction and get_on_query.

Right off the bat though, there is a couple things I can say.

  1. There is something off about your import PormG. You say you made module PormG in Main, in other words you have a Main.PormG. That can only be imported with a relative module “path”, like import ..PormG. Without the dots, it searches for and import packages, which does involve a module but exists in wholly separate files from anything you manually evaluated in Main. Now that I look closer, it also explains why the error mentions that a get_on_query(::PormG.SQLType) exists but get_on_query(::Main.PormG.SQLQuery) does not; the types come from different PormG, and the function came from the package PormG and can’t work on types from Main.PormG.

  2. I don’t think you moved myfunction at all, I think you created a distinct function in the distinct module with the same name and arguments. Here is a MWE:

julia> module A
        struct X end
        f(::X) = 0
       end
Main.A

julia> module B
         import ..A
         f(::A.X) = 1
       end
Main.B

julia> A.f === B.f
false

julia> A.f(A.X()), B.f(A.X())
(0, 1)

To instead reserve the names in module B for things imported from module A, specify the names in the import statement:

julia> module B
         import ..A: f, X, A
         f(::X) = 1 # replaces the method signature in A
       end
Main.B

julia> A.f === B.f
true

And listing A there is not redundant, import statements with colons lack the automatic import of the module name.

  1. The thread title is too vague as is, and there’s no indication the abstract type is the problem.
2 Likes

^Why was this marked as a solution? I didn’t solve anything.

Hi @Benny.

I’ve ever used julia to create scripts, but now I want to create my first pkg, so there are many stuffs that I don’t understand appropriately when studying the docs. One of this stuff is the use of .. when the module is a Pkg that I’m building. So, your explanation gives me a better knowledge about modules in julia.

That’s good, but did that knowledge lead you to fix the bug described in the original post? If so, you should acknowledge so, however briefly, and mark yourself as the solution so it is automatically linked below the original post. If not, this should be kept open until a post that fixes the bug arrives.

1 Like

Hi @Benny, Your answer fixes my code. So, I changed the title to be more clear. In addition, your explanation was very useful to beginners like me.

Oh, so separate modules sharing names did end up causing your error. Good that I could help, even if accidentally!

1 Like