println(@__MODULE__)Main
モジュールとパッケージ
司馬 博文
9/10/2020
1/01/2025
A Blog Entry on Bayesian Computation by an Applied Mathematician
$$
$$
Module は,Julia において名前空間を提供する.
documentation における Base.map などである.現在 Module 内では大域的な名前を,外部から参照不可能にする方法はない. 現在の Module は @__MODULE__ マクロで確認できる.
この時の ”method” の語は,OOP に似ている使い方であるが,やはり多重ディスパッチが意識されている.Julia の多重ディスパッチにおいて,関数とは method の張り合わせである.
module文とexport文:Module 定義my_functionはMyModule.my_functionの外部からアクセス可能な関数になる.
export文は,この module をusingした時に,何が取り込まれるかを指定する.
exportしていなかったグローバル変数global_varはモジュール内部では直接参照できても,外部からはMyModule.global_varとしてアクセスしないといけない.
module は入れ子式にできる.その際はA.B.fooというように参照する.
using文:既存の外部 Module から名前を輸入する:演算子:個別の名前だけを選んで取り込むとすると,Module 内部の変数・関数名は一切入れずに,Module 名だけ取り込む.
すると,Statistics.mean という形で利用できるようになる.using じゃ届かない import されていない名前も,全てこの方法でアクセスできる.1
using .MyModule名前はLOAD_PATH変数に沿って検索される.
REPL で定義した直後の module は Main.Module になっており,LOAD_PATH が通っていないので,using Module と言われてもわからない.
この場合は,相対 path で読み込む必要がある..Moduleでアクセスできる...は親の子モジュール,...は祖父母の子モジュールにアクセスする.ShellScript と同じ要領である.
include文:ファイルの分割Stringを path として評価し,そのファイルを見つけ出し,Julia 文として評価する.
path の構文は / を用いる.2
include 関数を REPL で使うと,相対 path は working directory からのものと解釈される.
Import文:拡張を許す取り込みまたusing文と違って,exportに制御された暗黙の取り込みがない.
importを使わない方法:
Base.length(v::MyType) = 3
構文と:演算子はusingと同じ.
PkgTemplates.jl (GitHub / Docs)3Documenter.jl (GitHub / Docs)ディレクトリごと作成する場合は:
既存のディレクトリを用いる場合は:
既存のプロジェクトを有効にして REPL を起動する場合は
この状態で
とすると,Project.tomlに依存関係が追記され,パッケージ内でusing Exampleとすることができるようになる.
プロジェクト(環境)とは,Project.tomlとManifest.toml(任意)を備えたディレクトリのことをいう.
Project.tomlはプロジェクトが読み込む名前空間と識別子を定義する.
これらのファイルは抽象的には次の3つの写像を定めている:
roots : name::Symbol \(\Longrightarrow\) uuid:UUID
パッケージ名nameに,一意なuuidを割り当てる.
環境内でimport Xという構文を見つけた際,Julia は識別子 roots[:X] を検索する.
graph : context::UUID \(\Longrightarrow\) name::Symbol \(\Longrightarrow\) uuid::UUID
roots とは違って,コンテクストによって変わり得る名前とUUIDの対応を定める.
paths : uuid::UUID \(\times\) name::Symbol \(\Longrightarrow\) path::String
uuidとnameの組に,パッケージのインストールされた場所を定める.
写像rootsはProject.tomlの[deps]セクションによって定義される.
PkgTemplates.jl を用いたパッケージの作成例えば次のようにして使う:
Project.toml の versions を更新する.git commit する.git tag -a v0.3.0 -m "Releasing version 0.3.0" でタグをつける.git push で GitHub にプッシュする.git push origin v0.3.0 や git push origin --tags でタグもプッシュ.Documenter.jl を用いたドキュメンテーションの作成Package Guide も参照.
docs/ ディレクトリ内に新たな環境を作成し,その環境に Documenter.jl をインストールする:
docs/make.jl を実行する:
これにより,docs/build/ ディレクトリにドキュメントが生成されるが,その内容はコミットしない.GitHub 上では documentation.yml によって gh-pages ブランチにのみプッシュされる.
*.md ファイルデフォルトでは index.md のみがあるが,自分で追加することもできる.
Debugger パッケージコード内に @bp でブレークポイントを設定し,デバッグしたい関数呼び出しに対して Debugger.@enter でデバッグを開始する.c でブレークポイントまで実行する.
基本的には,現在のスコープ内で次の行に行く n と,関数呼び出しに呼び込む s とを使って移動していく.s の取り消しは so でできる.
関数呼び出しの際,f(arg1, arg2, ...) という構文を評価するのに,実際に f が呼び出されるのは最後になったりする.このような場合は sl (step last) を使う.一般に f(g(h())) の形がある場合に,f に step in することになる.
出力されるコード脇の > は次のステップで実行しようとしている行を意味する.
w add expr によって watch list に変数を追加し,追加した変数の値は w で確認できる.
これで指定しないと何を取り込んだのかの制御が外部にあるままなので(module 定義内のexport文),共同開発の時は指定するのが良い.↩︎
Windows のように,Julia は/を使う.↩︎
日本語解説記事もある:Qiita (2023.9).↩︎