我正在尝试找出组织 Julia 应用程序 seqscan
源代码树的正确方法。现在我有以下树:
$ tree seqscan/
seqscan/
├── LICENSE
├── README.md
├── benchmark
├── doc
├── examples
├── src
│ └── seq.jl
└── test
└── test_seq.jl
5 directories, 4 files
文件seq.jl
包含
module SeqScan
module Seq
export SeqEntry
type SeqEntry
id
seq
scores
seq_type
end
end
end
和test_seq.jl
包含:
module TestSeq
using Base.Test
using SeqScan.Seq
@testset "Testing SeqEntry" begin
@testset "test SeqEntry creation" begin
seq_entry = SeqEntry("test", "atcg")
@test seq_entry.id == "test"
@test seq_entry.seq == "atcg"
end
end
end
但是,运行测试代码会产生错误:
ERROR: LoadError: ArgumentError: Module SeqScan not found in current path.
即使在将 JULIA_LOAD_PATH
环境变量设置为包含 seqscan
或 seqscan/src
之后,我一定是做错了什么?
最佳答案
包名(本地树的根)需要与 src 目录下存在的文件名相匹配。试试这个:
SeqScan/
|-- src/
|-- SeqScan.jl (your seq.jl)
我不知道你为什么要在 SeqScan 中封装 Seq 模块。如果没有重要的理由这样做,您可以更直接地访问该类型。您可以删除“module Seq”和成对的“end”。然后只要“使用 SeqScan”就会引入 SeqEntry 类型。
类型 SeqEntry 知道在给定四个字段值时要做什么,每个字段值对应一个已定义的字段。如果您只想用前两个字段初始化该类型,则需要包含一个双参数构造函数。例如,假设 seq 是某种数值类型的向量,而 scores 也是该数值类型的向量,并且 seq_type 是数值类型:
function SeqEntry(id, seq)
seq_type = typeof(seq[1])
scores = zeros(seq_type, length(seq))
return SeqEntry(id, seq, scores, seq_type)
end
用于 Julia v0.5 的带有内部模块的包示例。
包名为MyPackage.jl;它包含两个内部模块:TypeModule 和 FuncModule;每个模块都有自己的文件:TypeModule.jl 和 FuncModule.jl。
TypeModule 包含一个新类型 MyType。 FuncModule 包含一个新函数 MyFunc,它对 MyType 的变量 [s] 进行操作。该函数有两种形式,1-arg 和 2-arg 版本。
MyPackage 使用两个内部模块。它合并每个变量以供立即使用并初始化 MyType 的两个变量。然后 MyPackage 将 MyFunc 应用于它们并打印结果。
我假设 Julia 的包目录是“/you/.julia/v0.5”(Windows:“c:\you.julia\v0.5”),并将其称为 PkgDir。您可以通过在 Julia 的交互式提示符下键入 Pkg.dir() 来找到真正的包目录。首先要确保 Julia 的内部信息是最新的:> Pkg.update()
然后获取一个特殊的包调用 PkgDev:> Pkg.add("PkgDev")
您可以在 GitHub 上启动您的包。如果您在本地启动它,您应该使用 PkgDev,因为它使用正确的结构创建基本的包文件(和其他文件):
> 使用 PkgDev
然后 > PkgDev.generate("MyPackage","MIT")
这还会创建一个文件 LICENSE.md,其中包含 Julia 的首选许可证。您可以保留、更换或移除它。
在目录 PkgDir/MyPackage/src 中,创建一个子目录“internal”。在目录 PkgDir/MyPackage/src/internal 中,创建两个文件:“TypeModule.jl”和“FuncModule.jl”,它们是:
TypeModule.jl:
module TypeModule
export MyType
type MyType
value::Int
end
end # TypeModule
FuncModule.jl:
module FuncModule
export MyFunc
#=
!important!
TypeModule is included in MyPackage.jl before this module
This module gets MyType from MyPackage.jl, not directly.
Getting it directly would create mismatch of module indirection.
=#
import ..MyPackage: MyType
function MyFunc(x::MyType)
return x.value + 1
end
function MyFunc(x::MyType, y::MyType)
return x.value + y.value + 1
end
end # FuncModule
在 src 目录中,编辑 MyPackage.jl 使其匹配:
MyPackage.jl:
module MyPackage
export MyType, MyFunc
#=
!important! Do this before including FuncModule
because FuncModule.jl imports MyType from here.
MyType must be in use before including FuncModule.
=#
include( joinpath("internal", "TypeModule.jl") )
using .TypeModule # prefix the '.' to use an included module
include( joinpath("internal", "FuncModule.jl") )
using .FuncModule # prefix the '.' to use an included module
three = MyType(3)
five = MyType(5)
four = MyFunc(three)
eight = MyFunc(three, five)
# show that everything works
println()
println( string("MyFunc(three) = ", four) )
println( string("MyFunc(three, five) = ", eight) )
end # MyPackage
现在,运行 Julia 输入 > using MyPackage
应该会显示:
julia> using MyPackage
4 = MyFunc(three)
9 = MyFunc(three, five)
julia>
关于julia - 组织 Julia 源代码树的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40247888/