Juliaのパッケージ作成メモ
Julia の REPL を立ち上げて以下を実行すると雛形ができる。
runtests.jl や github workflow やら documenter やら色々ファイルを作ってくれる。
using PkgTemplates
Template(interactive=true)("ここにパッケージ名")
作成される場所は ~/.julia/dev
なので、他の場所に移したい場合は移した後に ~/.julia/dev/xxx
にシンボリックリンクを張る。
ローカル環境で以下コマンドを流すことでインストールした扱いになり普通に using Xxx
で使えるようになる。
向き先は開発中のパッケージフォルダなので、パッケージを変更してもアップデートは不要。
Pkg.development("ここにパッケージ名")
参考
初めてのことなのでどう開発するのが正解なのかわからないが、
VSCode(Juliaアドオンインストール)で立ち上げたREPLを主に使っている。
どこか適当な行で何も選択せず ctrl
+ Enter
を打って、VSCodeのターミナルにProject.toml を読み込んだ状態のREPLを立ち上げる。
このときキャプチャのように syntax: incomplete: premature end of input
とエラーが出るが気にせず該当行で Esc
を打って赤くなったハイライトを消す。
立ち上がったREPLで、
using Revise
を打って
using MyPkg
すると、リロードしなくても変更がREPLに反映される。
基本はREPLでごにょごにょコードを試しながらうまくいったらソースに書き写すみたいなことをしている。
(ブレークポイントとかの使い方は知らない)
仕事のRails開発では主にpryを使ってわからないことはオブジェクトに訊くみたいな感じでごにょごにょしてるが、Juliaはオブジェクト指向ではないので、データと振る舞いがカプセル化されているRuby(pry)と違って、REPL上の変数を捨てずに関数の定義を追加したり変更したりしても動くのがいいなと思った。(struct の変更はREPLの再起動が必要だけど)
テストは REPL上で ]
で test
と打つと、test/runtests.jl
が動く。
REPL上で ;
と打つとシェルに入れるのは、ファイルを消したり移したりするのに使ったり、もろもろ便利。
JuliaのREPLは優秀だなと思った。
以下のような感じでファイルを作っている。
src
├── including_functions.jl
├── MyPkg.jl
├── SomeModule1.jl
└── SomeModule2.jl
module
を持たない function
の集まりは snake_case.jl
module
を持つものは PascalCase.jl にしている。
module MyPkg
include("including_functions.jl")
include("SomeModule1.jl")
include("SomeModule2.jl")
function some_main_func()
end
end # module
function some_util_func()
end
module SomeModule1.jl
using ..MyPkg: SomeModule2
#using ..MyPkg: SomeModule2.bar ←これならbarを呼べるが。。
using .SomeModule2
function foo()
end
module SomeModule2.jl
export: bar
function bar()
end
include
, import
, export
, using
をどうするのが正解かわからないが、
パッケージ本体の MyPkg.jl
にもろもろ include
させてる。
各モジュール間で使いたい関数やら構造体を受け取りたい場合は、
using ..MyPkg: SomeModule2
using .SomeModule2
のようにしている。
パッケージ本体は ..
とピリオド2つ。
使いたい関数やら構造体を持っているモジュールを .
とピリオド1つで呼ぶ。
Xxx: Yyy
のように :
をつけると指定したものだけ呼べるが、さらにその下の Yyy
が持っている関数や構造体は export
で定義していても呼び出せず UndefVarError
と怒られる。
MyPkg
側でも export
定義すれば呼べるんだろうがそれもやりたいことと違うので、
冗長だが
using ..MyPkg: SomeModule2
でパッケージ本体のうち使いたいモジュールを呼んで、
using .SomeModule2
で使いたいモジュールが持っている関数や構造体を持ってくる。
REPLでモジュールの中のコードを動かしたい場合は、
julia> using Revise
julia> using MyPkg
julia> using MyPkg.SomeModule1
とすると、 SomeModule1
が持っている関数やら構造体が展開されたREPLになるので、そこでごにょごにょする。