I am having trouble with defining a non-default constructor. See code snippet below,
type AType
a::Float64
end
type BType
b::Float64
Btype(a_type::AType)=new(a_var.a)
end
a_var=AType(5.0)
b_var=BType(a_var)
While trying to invoke the non-default constructor for BType I get an error that reads,
LoadError: MethodError: Cannot `convert` an object of type AType to an object of type BType
This may have arisen from a call to the constructor BType(...),
What am I doing wrong?
Thanks!
You have a capitalization typo: Btype(a_type::AType)=new(a_var.a)
should be BType
Actually, I was planning to ask a completely different question (got distracted by silly typos…)
The problem I encountered is trying to split the above code into to several modules.
Explicitly, I define AType and BType in A.jl and B.jl respectively and then construct BType from Atype in C.jl. See below,
A.jl
module A
export AType
type AType
a::Float64
end
end
B.jl
module B
export BType
include("./A.jl")
using .A
type BType
b::Float64
BType(a_type::AType)=new(a_type.a)
end
end
and C.jl
module C
include("./A.jl")
include("./B.jl")
using .A
using .B
a_var=AType(5.0)
b_var=BType(a_var)
end
I get the following Error,
LoadError: MethodError: Cannot `convert` an object of type C.A.AType to an object of type C.B.BType
This may have arisen from a call to the constructor C.B.BType(...),
since type constructors fall back to convert methods.
in C.B.BType(::C.A.AType) at ./sysimg.jl:53
I was basically trying to imitate C++ include system but I guess that doesn’t really work here.
I have noticed that including a module from an external file appends the current “namespace”, is the source of error? If so how can I avoid this behavior?
Manage include explicitly and include each file only once.
Thanks for the quick reply.
Just to make this more concrete, I have removed the include statements appearing in A.jl and B.jl ( I still keep them in C.jl). Now, running C.jl results in an error corresponding to the fact that module B doesn’t recognize module A:
LoadError: LoadError: UndefVarError: A not defined
How can I make module A visible in module B (or more generally to code in B.jl).
You should do
# C.jl
module C
# A.jl
module A
# ...
end
# `using .A` if you want to bring exports into `C`'s scope
# B.jl
module B
using .A
# ...
end
end
Thanks again for the quick reply!
I must be missing something very basic here…
Here is my revised code (in an attempt to follow your suggestions):
# A.jl
module A
export AType
type AType
a::Float64
end
end
# B.jl
module B
export BType
using .A
type BType
b::Float64
BType(a_type::AType)=new(a_type.a)
end
end
and
# C.jl
module C
include("./A.jl")
using .A
a_var=AType(5.0)
include("./B.jl")
using .B
b_var=BType(a_var)
end
I still get an error, which as far as I understand is related to the visibility of “A” in “B”.
LoadError: LoadError: UndefVarError: A not defined
in include_from_node1(::String) at ./loading.jl:488
in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in include_string(::String, ::String) at ./loading.jl:441
in include_string(::String, ::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in include_string(::Module, ::String, ::String) at /Users/snirgaz/.julia/v0.5/CodeTools/src/eval.jl:32
in (::Atom.##61#64{String,String})() at /Users/snirgaz/.julia/v0.5/Atom/src/eval.jl:81
in withpath(::Atom.##61#64{String,String}, ::String) at /Users/snirgaz/.julia/v0.5/CodeTools/src/utils.jl:30
in withpath(::Function, ::String) at /Users/snirgaz/.julia/v0.5/Atom/src/eval.jl:46
in macro expansion at /Users/snirgaz/.julia/v0.5/Atom/src/eval.jl:79 [inlined]
in (::Atom.##60#63{String,String})() at ./task.jl:60
while loading /Users/snirgaz/Code/./B.jl, in expression starting on line 3
while loading /Users/snirgaz/Code/C.jl, in expression starting on line 5
Thanks!