Julia 工程实践速记
在用 Julia 尝试了一些数据分析的例子之后,让我们先停下来探索其在数据分析方面其他的能力,转而去看看 Julia 工程实践方面的一些注意点。从某种程度上来讲,本文也可以算是对于我前段时间用 Julia 给DTeam团队日志实现了一个简单的文章推荐 API 服务的总结。
REPL
首先说一下 REPL 环境,它具备以下工作模式:
- 脚本执行,这是缺省模式,启动之后就直接进入该模式;
- 包管理,键入 “]” 就进入这个模式,在此模式下可以进行包和开发环境的管理,这会在后面详细介绍;
- shell 模式,键入 “;” 将进入该模式,在此模式下可以执行 shell 命令,但令人不爽的是每次执行完之后就会回到脚本执行模式,假如你想执行多个命令,就不得不每次都先敲一下“;”;
- help 模式,键入 “?” 将进入该模式,在此模式下可以查阅 julia 的各个函数说明。
对于有过 VIM 使用经验的开发者来讲,这种工作方式并不陌生,通过上面的几种方式,可以在不离开 julia REPL 环境下就能完成多种不同类型的任务,还是非常方便的。
同时,建议安装两个包,它们会极大改善你的生活:
- OhMyREPL,不仅有语法着色,而且还能自动补全括号,至于其他特性请自行参见文档。
- Revise,在不必重新启动 Julia 环境的情况下,自动重新加载改变后的文件。
并且,对于 OhMyREPL ,建议在启动 REPL 时就使用它。由于 REPL 在启动时会自动执行 ~/.julia/config/startup.jl ,因此在其中启用它是最自然的事情。请添加下面的代码:
try
using OhMyREPL
catch
@warn "OhMyREPL not installed"
vscode extension
vscode 的 julia extension 相当不错,除了常规这类插件该做的事情,它还能在保存文件时自动格式化代码,并且最让人觉得不错的就是,它会自动识别出你 julia 工程的环境,从而进入该环境。请注意,这里指的工程环境指的是类似 python virtualenv 支持的那种环境。
对于 julia ide,我推荐 vscode + julia extension ,虽然官方推荐 juno 。julia extension 的安装也没什么特别的,在 extension 中搜索 “julia” ,安装排名第一的那个就行了。
Pkg
Pkg 这个名字很具有迷惑性。单从名字上看,感觉它就是一个简单的包管理器,类似 python 下的 pip 。其实际上它具备三大功能:
- 包管理器,类似 pip;
- 环境管理器,类似 virtualenv;
- 构建工具,类似 gradle。
包管理
先看包管理器,Pkg 的包管理功能围绕 git 来构建。这样做的好处:
- 使用正常发布的包;
- 使用处于开发中的包:换不同分支即可;
- 使用私有包:地址指向私有包的 git url 即可;
- 使用某版本的包:在包名中加上版本字符串;
作为包管理的常见命令:add,增加包;up,更新包;pin,指定包不随 up 命令更新而更新;rm,不再使用包;gc,从硬盘中删除没有被一个工程引用的包。
关于包管理功能的其余命令,请参见相应文档,这里不再赘述。
本来也应该介绍一下包仓库的内容,但从开发角度来讲,并不是初学者必须掌握的内容,讲多了反而啰嗦,对于一篇速记来讲就没有必要单独点出了。还是那句话,请看文档。
环境管理器
我在那篇时序分析的文章中曾说过 julia 缺乏好的环境管理器,这里必须承认当时的不严谨。从 julia 1.0 开始,Pkg 就接过了环境管理的任务,实现了类似 python 中的 virtualenv 的功能。这一点是令人欣喜的,毕竟官方默认就已经实现这个功能了,无需再去装其他的第三方包,简化了工作流程。
如果你不理解环境为何那么重要,想想看在 Python 中经常遇到的:你的代码在某版本下工作好好的,某天升级 Python 或某个包之后,代码立马不工作了。这就是因为没有做好环境隔离,导致的。我就有过亲身惨痛经历,导致我不得不把整个环境重新梳理了一遍。
julia 的环境名默认就是目录名,进入某个某目录之后,在 Pkg> 下输入 “activate .” 就进去了。而且,假如从 vscode 进去,它会自动发现,并提示你是否进入,前题是该目录是一个包工程。
构建工具
有过 gradle 这类构建工具的开发者会很高兴看到 julia 缺省就提供了构建工具,不再需要单独安装,避免了选择的烦恼。做够构建工具,Pkg 的常用命令:
- generate,创建工程,此时会创建一个目录;
- build,构建,它会执行 “deps/build.jl” 中的语句;
- test,测试,它会执行 “test/runtests.jl” 中的语句(关于 julia 的测试,值得写另一篇文章了)。
因此,典型的 julia 工程的目录结构应该是
.
├── Project.toml
├── deps
│ ├── build.jl
├── src
│ └── hello.jl
└── test
└── runtests.jl
这里请注意,generate 命令只会产生 src、src/xxx.jl、Project.toml,至于 build.jl 和 runtest.jl ,以及相关目录,你得自己手工去创建。并且,build.jl 的输出也是在 deps/build.log 中。
至于如何将包发布到仓库中,可以参见 Registrator.jl 。
并且,假如你想快速在另一台机器上从已有工程中恢复环境,可以:
julia> download(url, "project.toml")
pkg> activate .
pkg> instantiate
最后简单总结一下 julia 工程的简单工作流程:
- generate 工程名
- 进入工程目录
- activate .
- add 需要的包
- 开发
- 写测试,在 test/runtests.jl 中
- test
- 写构建脚本,在 deps/build.jl 中
- build
另外,我发现这篇老文章也值得参考,虽然使用的 julia 版本已经久远,但仍然有参考价值。