Functions in a Module can't resolve convert routines defined in the module?



Hi all,

I’m writing my first non-trivial Julia project. I’ve run into a problem I can’t quite figure out. I want to use quaternions from the Quaternion package and send them to a C library that takes quaternions as a four element Float32 array. So I’ve written the following convert routine:

unsafe_convert(::Type{Ptr{Float32}}, q::Quaternions.Quaternion{Float64}) =
    convert(Ptr{Float32}, Ptr{Float32}(pointer_from_objref([imag(q), real(q)])))

which is declared inside the module that needs it. This code works fine from the REPL, I get the following:

julia> q = Quaternion(1.0, 0.0, 0.0, 0.0)
1.0 + 0.0im + 0.0jm + 0.0km

julia> x = Ptr{Float32}

julia> unsafe_convert(x, q)
Ptr{Float32} @0x0000000113d2a890

But when I put it in the module and try to use I get the following:

julia> include("distance_example.jl")
WARNING: replacing module Distance
ERROR: LoadError: MethodError: no method matching unsafe_convert(::Type{Ptr{Float32}}, ::Quaternions.Quaternion{Float64})
Closest candidates are:


When you defined your method for unsafe_convert, did you extend the method from Base? If not, try defining your method as Base.unsafe_convert(...) = ..., i.e. qualifying the call so that Julia knows to overload unsafe_convert rather than define a new local function called unsafe_convert.


OK, that worked. Thanks!

Why did it work, though? Julia doesn’t know to automatically call a locally defined unsafe_convert to do a conversion?


No, since conversions call Base.unsafe_convert, and what you’ve (implicitly) defined is Main.unsafe_convert. In general names aren’t significant unless you’re extending methods from other modules.


Julia doesn’t extend another package’s functions unless you explicitly tell it to by qualifying like Base.unsafe_convert or having an import Base: unsafe_convert somewhere. If you don’t tell julia to extend the function than you’re defining a new function with the same name inside your package.