Julia - VSCode で Julia 1.0 を使う (仮)
julia-vscode v0.11.0 から Julia 1.0 に対応したのでこの記事を読む必要はありません。master ブランチのものを入れたい場合は手順だけ参考になるかもしれません。(2019/1/29)
現状、VSCode の Marketplace から入れることの出来る Julia の拡張機能を使うと、Julia 1.0 では REPL を起動することができません。
Julia 拡張の Wiki には一応 Julia 1.0 でのやり方も書いてあるのですが、初見では私にはさっぱりわかりませんでした*1。 この点に関しては調べたらすぐに解決したのでよいのですが、Plot Pane にプロットを表示させる方法はソースコードを読まないと解決できないと思うので記録として残しておきます。*2
Julia 拡張の README に書いてある以下の機能の内 syntax highlighting, snippets, integrated julia REPL の3つは使えました。*3
- syntax highlighting
- snippets
- latex snippets
- julia specific commands
- integrated julia REPL
- code completion
- hover help
- a linter
- code navigation
- tasks for running tests, builds, benchmarks and build documentation
環境
- OS: ArchLinux
- Julia 1.0.1
- npm 6.4.1
- typescript 3.1.1
- VSCode 1.28.1
julia extension を入れる
Wiki には julia-vscode を開発している方のリポジトリを使うようにとありますが、 現在の julia-vscode の master ブランチにはその方の PR がマージされているので本家の master を使います。 すでに過去の Julia 拡張をインストールしてある場合はそれを消去してください。
sudo pacman -S npm typescript # Ubuntu の場合は sudo apt install npm node-typescript cd ~/.vscode/extensions git clone https://github.com/JuliaEditorSupport/julia-vscode cd julia-vscode npm run update2latest
これだけで REPL は使えるようになると思います。適当な Julia のファイルを開いて Ctrl-Enter をすれば REPL 上で実行されるはずです。
Plots.jl での描写を Plot Pane に出力する
私の環境では何も考えずに Julia 1.0 で
using Plots
plot(sin)
とすると、backend に PyPlot を指定した場合は、
/usr/lib/python3.7/site-packages/matplotlib/figure.py:457: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure "matplotlib is currently using a non-GUI backend, "
と出るだけでプロットは表示されず、GR を使った場合は別枠のウィンドウが開きました。
Julia 0.7 だとちゃんと Plot Pane にプロットされるんですけどね。不思議です。
using Plots
popdisplay()
plot(sin)
とするとちゃんと Plot Pane に表示されます。

何故 popdisplay() すると上手くいくのか気になる人は Plots.jl と Julia 本体のソースコードを読んでください。
参考
- J0.7/1.0 update by ZacLN · Pull Request #541 · JuliaEditorSupport/julia-vscode · GitHub
- Plots.jl/init.jl at 1e83bc05ee791e84d038248c5bfe9b8ab424bfd1 · JuliaPlots/Plots.jl · GitHub
- julia/multimedia.jl at eabb601ec8cccb4ff40f18eb4f046ab4608f1840 · JuliaLang/julia · GitHub
*1:私は JavaScript 使ったことありません
*2:issue 出したので現在はすぐに解決策見つかりますけど。
Julia - 関数の broadcast ( f.(arg...) ) をオーバーロードする方法
どこで使うと便利なのかわからないけれど、一応できたのでメモ。
公式ドキュメントだけでこの方法を思いつく人は相当訓練された Julian だと思う(思いたい)。
Julia 1.0 でのやり方
f.(arg...) の挙動を変えたい場合、broadcast でなく、broadcastedをオーバーロードすれば良い。
julia> f(x) = println("Normal") f (generic function with 1 method) julia> f(1) Normal julia> f.(1) Normal # 第一引数を `::typeof(挙動を変えたい関数)` とするのがミソ julia> Base.Broadcast.broadcasted(::typeof(f), x) = println("Broadcast") julia> f(1) Normal julia> f.(1) Broadcast julia> f.([1,2]) Broadcast
上手くいかない方法
ドキュメントに
A special syntax exists for broadcasting: f.(args...) is equivalent to broadcast(f, args...)
とあるけど、broadcast をオーバーロードすればいいわけではない。
julia> f(x) = println("Normal") f (generic function with 1 method) julia> f(1) Normal julia> f.(1) Normal julia> f.(x::Int) = println("Broadcast") ERROR: syntax: invalid syntax "f.(x::Int) = ..." julia> Base.broadcast(f, x::Int)= println("Broadcast") julia> f(1) Normal julia> f.(1) Normal julia> Base.broadcast(::typeof(f), x::Int)= println("Broadcast") julia> f.(1) Normal julia> f.([1,2]) Normal Normal 2-element Array{Nothing,1}: nothing nothing
Julia 0.6 のときは broadcast をオーバーロードすればよかった。
julia> f(x) = println("Default") f (generic function with 1 method) julia> f(1) Default julia> f.(1) Default julia> Base.broadcast(::typeof(f), x) = println("Broadcast") julia> f(1) Default julia> f.(1) # ここの挙動が Julia 1.0 と違う Default julia> f.([1, 2]) Broadcast
参考
x.*x not customizable · Issue #22053 · JuliaLang/julia · GitHub
Julia - 定義した method を消す方法
環境
Julia 1.0
無駄な method を消す
Julia といえば多重ディスパッチが有名ですよね*1。
julia> f(x::Int64) = println("Intだよ") f (generic function with 1 method) julia> f(x::Float64) = println("Floatだよ") f (generic function with 2 methods) julia> f(Int64(1)) Intだよ julia> f(Float64(1)) Floatだよ
こんな感じに同じ関数でも引数の型を指定して定義することで、型に応じて動作を変えることができるので便利です。
しかし、ここで一つ問題があります。
上記の例では引数が Int64 だったら Intだよ と出力するようにしましたが、後々になって Integer の subtype 全体に対して 整数だよ と出力したくなったとしましょう。
素直に考えたら次のように定義すると思います。
julia> f(x::Integer) = println("整数だよ") f (generic function with 3 methods)
しかし、この定義の仕方だと Int64 の数値を入れると一番初めに定義した method が呼び出されてしまいます。
julia> f(Int32(1)) 整数だよ julia> f(Int64(1)) Intだよ julia> methods(f) # 3 methods for generic function "f": [1] f(x::Float64) in Main at REPL[2]:1 [2] f(x::Int64) in Main at REPL[1]:1 [3] f(x::Integer) in Main at REPL[5]:1
単純な対処法は f(x::Int64) を上書きしてしまうことでしょう。
f(x::Int64) = println("整数だよ")
しかし、また気が変わって Integer の subtype 全体に対して Intだよ と出力したくなった場合、f(x::Int64) と f(x::Integer) の2つを上書きしなければなりません。これはどう考えても面倒です。
f(x::Int64) = println("Intだよ") f(x::Integer) = println("Intだよ")
今は Integer の subtype ならば全て同じ動作にしたいので f(x::Int64) が邪魔です。いっそなかったことにしたいです。
そんな時に便利なのが Base.delete_method です。2018/9/24 現在公式ドキュメントに記述は一切ありません。
which と組み合わせて以下のように使います。
julia> f(Int64(1)) Intだよ julia> Base.delete_method(@which f(Int64(1))) julia> f(Int64(1)) 整数だよ julia> methods(f) # 2 methods for generic function "f": [1] f(x::Float64) in Main at REPL[2]:1 [2] f(x::Integer) in Main at REPL[5]:1
見事に f(x::Int64) の method が消えました。@which マクロを使う場合は消したい method の具体的な値を入れてください。which を使う場合、
Base.delete_method( which(f, (Int64, ) ) )
と書きます。具体的な値を入れてしまう方が楽だとは思いますが、「この型の method を消してるんだぞ!」と強調したいときは which 使うと良いのではないでしょうか。
とまぁ、無事に不必要な method を消すことができた訳ですが、正直に言ってこの程度のことだったら一度プロセスを切ってもう一度 Julia を起動し直したほうが断然楽ですね。
ものすごく読み込みが遅いパッケージを使っている最中ならば Base.delete_method を使ったほうが楽かもしれませんが、大抵の場合は再起動したほうが早いでしょう。
上記の例ではあまりメリットを感じないので、もう少し実用的なものを考えてみましょう。私は pretty-print 好きなので pretty-print に応用しましょう*2。
pretty-print
julia> 1.0 + im 1.0 + 1.0im julia> function Base.show(io::IO, z::Complex{Float64}) r = round(abs(z), digits=3) θ = round(atan(z.im, z.re), digits=3) print(io, r, " * ( cos( ", θ, " ), sin( ", θ, " ) )") end julia> 1.0 + im 1.414 * ( cos( 0.785 ), sin( 0.785 ) )
定義した method を消します。
julia> Base.delete_method(which(Base.show, (IO, Complex{Float64}))) julia> 1.0 + im 1.0 + 1.0im
どうですか!今までは pretty-print を自分で定義した場合、元の書式に戻すには再起動するしかなかったのに Base.delete_method を使うことで再起動を回避できたではありませんか!!!
とはいえ、これでは切り替えが面倒なので簡単に切り替えできるように関数を定義しましょう。
julia> 1.0 + im 1.0 + 1.0im julia> POLAR = false false julia> function polarform(x::Bool) if !POLAR && x eval(quote function Base.show(io::IO, z::Complex{Float64}) r = round(abs(z), digits=3) θ = round(atan(z.im, z.re), digits=3) print(io, r, " * ( cos( ", θ, " ), sin( ", θ, " ) )") end end) global POLAR = true return end if POLAR && !x Base.delete_method(which(Base.show, (IO, Complex{Float64}))) global POLAR = false return end end polarform (generic function with 1 method) julia> polarform(true) julia> 1.0 + im 1.414 * ( cos( 0.785 ), sin( 0.785 ) ) julia> polarform(false) julia> 1.0 + im 1.0 + 1.0im
polarform(true) にすると極形式で、polarform(false) にすると Cartesian Form*3 で表示することに成功しました!
ついに私は pretty-print の切替方法を確立してしまった。 今後のパッケージ作りに役に立ちそうだ。
落とし穴
先程の pretty-print の例では Base.delete_method を使えばいつでもデフォルトの pretty-print に戻せるように感じたかもしれませんが、そんなことは全くもってありません。
複素数の pretty-print に関しては Complex{Float64} の supertype である Complex にのみ定義されているから先程の例は上手くいっただけで、普通はこんなに上手くいかないので注意してください。
export されてもいなければ、公式ドキュメントにすら書かれていない、エンドユーザーが使うことを想定してない関数がそんなにおいしいわけないですね。
julia> 1.0+im 1.0 + 1.0im julia> Complex{Float64} <: Complex true julia> @which show(stdout, 1.0+im) show(io::IO, z::Complex) in Base at complex.jl:183 julia> Base.delete_method(@which Base.show(stdout, 1.0+im)) julia> 1.0+im Complex{Float64}(1.0, 1.0) julia> @which show(stdout, 1.0+im) show(io::IO, x) in Base at show.jl:315 julia> Base.delete_method(@which Base.show(stdout, 1.0+im)) julia> @which show(stdout, 1.0+im) ERROR: no unique matching method found for the specified argument types Stacktrace: [1] which(::Any, ::Any) at ./reflection.jl:922 [2] top-level scope at none:0 julia> 1.0+im Error showing value of type Complex{Float64}: ERROR: MethodError: no method matching display(::Complex{Float64}) Closest candidates are: display(::Any) at multimedia.jl:284 display(::AbstractDisplay, ::AbstractString, ::Any) at multimedia.jl:178 display(::AbstractString, ::Any) at multimedia.jl:179 ... Stacktrace: [1] display(::Complex{Float64}) at ./multimedia.jl:294
参考
LICENSE
- Copyright 2018 goropikari
- Licensed under MIT:
Julia - 野良パッケージをパッケージ名だけで追加できるようにする: Custom General Repository の作り方
Julia でパッケージを追加する場合、pkg mode で
(v1.0) pkg> add Example
などとすれば良いですよね、公式パッケージ*1の場合は。
野良パッケージの場合は次の例のように github の URL を打ち込まないといけません。
(v1.0) pkg> add https://github.com/goropikari/MyPackage.jl
パッケージ名だけならともかく URL を打ち込まないといけないというのは面倒です。公式パッケージ同様パッケージ名だけで追加したいと思うのは当然の願いでしょう。
この記事では Custom General Repository を作り、公式パッケージ同様 野良パッケージもパッケージ名だけで追加できるようにする方法を紹介します。
上手くいくとこんな感じで野良パッケージがパッケージ名だけで追加することができるようになります。
目次
Custom General Repository とは何か?と普通の人なら思うでしょう。無理もありません、便宜上私がそう呼んでいるだけですから。 Julia 0.x 時代のパッケージマネージャーはパッケージの情報を METADATA から参照していましたが、Julia 1.0 からは
METADATA に変わり General を参照するようになりました。 それで、これから我々がやろうとしていることを Julia 0.x 時代は Custom METADATA Repository と呼称していたので Custom General Repository としただけです。 現状の Julia では、パッケージ名で追加できるパッケージ と 公式パッケージ は同値です。 しかし、以前の記事にも書きましたが、公式パッケージにするためには README を英語で書いて、やりとりも英語でしなければならないので、非ネイティブな我々日本人にとってはハードルが高いものになっていることも事実でしょう。
おまけにレビュー付きなので「ちょっと練習がてら空のパッケージ登録をしてみよ」なんてことも出来ません。 また、ローカルのコミュニティでしか使わないパッケージを運用したい場合や、" 田中コレクション " といった独自のパッケージ群を提供したい場合なども公式パッケージに登録することは適しているとは言えないでしょう。 そんな時に便利なのが Custom General Repository です。これを作ることによって自分たちの裁量によって野良パッケージを自分の General に登録することができ、公式パッケージ同様にパッケージ名だけでパッケージを追加することができるようになります。 Youtuber の 「チャンネル登録はこちら」ではありませんが、「私のパッケージ群を使いたい場合はこの URL を git clone♪」とするだけで他の人たちは気軽にあなたのパッケージを使えるようになります。 以下の内容は私が実験しながら模索した方法であり、公式のやり方ではありません。そもそも、公式ドキュメントに独自の General を作るやり方は 2018/9/22 現在書いてありません*2。 先にどんなものなのか試したい人は MyGeneral を配置する を読んでください。 まずはご自身の github にパッケージを管理するためのリポジトリを作ってください。ローカルネットワーク内のディレクトリなどでも良いのですが、わかりやすさのため今回は github で作ります。リポジトリの名前は何でもよいですが、ここでは 以下はこの 作ったリポジトリをクローンしてきて必要なファイルを作っておきます。 name を作ったリポジトリ名 uuid は適当に 続く 現在のディレクトリ構成 続いて Compat.toml, Deps.toml, Versions.toml, Package.toml に必要な情報を書いていきます。 ハッシュ値は GameOfLife.jl パッケージ本体*4のディレクトリ上で とすると調べることができます。 対応している Julia のバージョンなどを書きます。Pkg.jl のドキュメント に書いてある方法に従えば良いと思いますが、当面は以下のように書いておけばよいでしょう。 パッケージの情報を書きます。uuid は MyPackage.jl の方も同様にして追加し、github に push します。 作った Julia を起動し、パッケージ情報をアップデートするといつもの 無事に野良パッケージをパッケージ名だけで追加することに成功しました。
他の人の Genaral も 公式パッケージの情報が入っている 以上 Custom General Repository の作り方の紹介でした。お疲れ様でした。 この記事の内容を使えば、公式パッケージにしなくてもパッケージ名だけで追加できるようになりますが、みなさんには是非公式パッケージ作りにチャレンジしていただきたいです。 Julia 1.0 がリリースされてから、Julia を「使ってみた」といったコメントは目にするようになりましたが、「パッケージを作った」という報告は全然目にしない気がします。野良パッケージですらその状況なので公式パッケージではなおのことです。 この記事で使った MyGeneral 等は以下です。必要ならばご自由にご覧ください。*5環境
OS 依存する内容ではありませんが、Linux コマンドを使っているので適宜脳内変換してください。Custom General Repository
Custom General Repository とは?
Custom General Repository を作るメリット
Custom General Repository を作る
MyGeneral としました。MyGeneral に私の野良パッケージ GameOfLife.jl と MyPackage.jl を登録するまでの流れです。先頭が $ から始まるものは bash での操作を表します。$ git clone https://github.com/goropikari/MyGeneral.git
$ cd MyGenaral
$ touch Registry.toml
$ mkdir GameOfLife
$ cd GameOfLife
$ touch Compat.toml Deps.toml Versions.toml Package.toml
Registry.toml の中身はこんな感じ。name = "MyGeneral"
uuid = "0d136408-be1b-11e8-146b-1b5bc37d4128"
repo = "https://github.com/goropikari/MyGeneral.git"
[packages]
b53c8852-a93e-11e8-3341-5bdef8841476 = { name = "GameOfLife", path = "GameOfLife" }
MyGeneral にする。generate MyGeneral して出てきたものを使いました。(v1.0) pkg> generate MyGeneral
Generating project MyGeneral:
MyGeneral/Project.toml
MyGeneral/src/MyGeneral.jl
shell> cat MyGeneral/Project.toml
authors = ["goropikari <goropikari56@gmail.com>"]
name = "MyGeneral"
uuid = "0d136408-be1b-11e8-146b-1b5bc37d4128"
version = "0.1.0"
[deps]
repo にはリポジトリがある URL を入れてください。[packages] の項目ですが、初めの謎の文字列は GameOfLife.jl の Project.toml に記載されている uuid です。path には GameOfLife.jl の情報が書かれているファイル*3がある場所を指します。今は MyGeneral の直下に置いたので ./GameOfLife となっています。MyGeneral/
├── GameOfLife
│ ├── Compat.toml
│ ├── Deps.toml
│ ├── Package.toml
│ └── Versions.toml
└── Registry.toml
Deps.tomlGameOfLife.jl の Project.toml の [deps] に書いてあったものをそのまま書きます。
最初の ["0.1"] は GameOfLife.jl のバージョン 0.1.0 の意味です。
要するに GameOfLife.jlのバージョン x.x.x はこれらのパッケージに依存してますよ〜と書かれているのが Deps.tomlです。["0.1"]
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Versions.tomlGameOfLife.jl の tree オブジェクト の SHA-1ハッシュ を書きます。["0.1.0"]
git-tree-sha1 = "0ea24bdd852ad9505eab96815e6f2c4dadffc018"
$ git cat-file -p HEAD
tree 0ea24bdd852ad9505eab96815e6f2c4dadffc018
parent 2f5c85c856f67d2db3152801507f30b640a83849
author goropikari <goropikari56@gmail.com> 1535299189 +0900
committer goropikari <goropikari56@gmail.com> 1535299189 +0900
Compat.toml["0.1"]
julia = "0.7-1.1"
Package.toml
Project.toml に書いてあるものを書きます。
repo にはパッケージが置いてある github URL を書いておきます。name = "GameOfLife"
uuid = "b53c8852-a93e-11e8-3341-5bdef8841476"
repo = "https://github.com/goropikari/GameOfLife.jl.git"
push する
$ git add -A
$ git commit -m 'first commit'
$ git push
MyGeneral を配置する
MyGeneral を ~/.julia/registries に配置します。$ julia -e 'using Pkg; Pkg.update()'
$ cd ~/.julia/registries
$ git clone https://github.com/goropikari/MyGeneral.git
https://github.com/JuliaRegistries/General.git に加えて
https://github.com/goropikari/MyGeneral.gitも読みにいっていることがわかります。(v1.0) pkg> up
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Updating registry at `~/.julia/registries/MyGeneral`
Updating git-repo `https://github.com/goropikari/MyGeneral.git`
Resolving package versions...
(v1.0) pkg> add GameOfLife
Resolving package versions...
Installed GameOfLife ─ v0.1.0
Updating `~/.julia/environments/v1.0/Project.toml`
[b53c8852] + GameOfLife v0.1.0
Updating `~/.julia/environments/v1.0/Manifest.toml`
[b53c8852] + GameOfLife v0.1.0
[2a0f44e3] + Base64
[b77e0a4c] + InteractiveUtils
[8f399da3] + Libdl
[37e2e46d] + LinearAlgebra
[d6f4376e] + Markdown
[3fa0cd96] + REPL
[6462fe0b] + Sockets
(v1.0) pkg> add MyPackage
Resolving package versions...
Installed MyPackage ─ v0.1.0
Updating `~/.julia/environments/v1.0/Project.toml`
[f41f8282] + MyPackage v0.1.0
Updating `~/.julia/environments/v1.0/Manifest.toml`
[f41f8282] + MyPackage v0.1.0
[9a3f8284] + Random
[9e88b42a] + Serialization
julia> using MyPackage
[ Info: Precompiling MyPackage [f41f8282-a16f-11e8-2120-1f4619698387]
julia> MyPackage.greet()
Hello World!
~/.julia/registries にクローンしてくれば同様にパッケージを追加することが出来ます。また、初回の git clone 以降はパッケージマネージャーが pull してきてくれます。ちなみに
~/.julia/registries/General を消すと、パッケージマネージャーは自分のリポジトリしか見に行かなくなるので、世間から切り離された孤独感を味わうことが出来ます。$ rm -rf ~/.julia/registries/General
$ julia -q
(v1.0) pkg> up
Updating registry at `~/.julia/registries/MyGeneral`
Updating git-repo `https://github.com/goropikari/MyGeneral.git`
Resolving package versions...
Updating `~/.julia/environments/v1.0/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.0/Manifest.toml`
[no changes]
おわりに
私も他の方のパッケージ作りに興味がありますし、まだまだわからないことも多いので情報を共有していただけると嬉しく思います。
Julia - 野良パッケージを公式パッケージにする方法
先日、DiracNotation.jl という拙作が METADATA.jl にマージされ、野良パッケージから公式パッケージ*1へと昇格しました。 Julia 1.0 が出て以降では初めてパッケージを新規登録したので不安もあったのですが、とりあえず無事にマージされてほっとしています。
最近、METADATA.jl を覗いていると新規のパッケージ登録も多く見られるので、自分のパッケージも公式パッケージにしたくてウズウズしている Japanese Julian*2 もきっと多いことでしょう。
しかし、Julia 1.0 になって公式ドキュメントから公式パッケージへの登録方法が消え、またパッケージの管理方法も変わったので、どうしたら公式パッケージとして登録できるのか分からず困っている Julian も多いのではないでしょうか。
そこで今回は野良パッケージを公式パッケージに登録するまでの方法を紹介します。
(注) Julia 1.0 がリリースされてから1ヶ月以上経ちましたが、既存のパッケージの Julia 1.0 への対応だったり、Bug fix に追われているせいか、パッケージの作り方・登録の仕方に関しては後回しになって曖昧な状態になっていると感じます。
パッケージのテンプレートを作ってくれる PkgDev.jl もまだ Julia 1.0 に対応していませんし。
そのため、ここで書いたことが1週間後、1ヶ月後にも通用する保証はありません。
目次
環境
- Julia 1.0
対象
本記事は以下の項目全てを満たす方を対象としています。
必要なもの
- 英語で質問された時に下手でも良いから伝えようとする気持ち
- 自分のパッケージを公式パッケージにしても良いだろうという根拠のない自信
- METADATA.jl に PR を投げる勇気
野良パッケージ作り
野良パッケージを作っていない人は、まずは野良パッケージを作ってください。大雑把な作り方に関しては過去の記事をご覧ください。
基本的なパッケージ構成
以降では今回私が作った DiracNotation.jl を元に具体的に説明していきます。
パッケージの最小構成は以下のようになっています。
DiracNotation.jl/ ├── .git ├── .gitignore ├── LICENSE.md ├── README.md ├── REQUIRE ├── src │ └── DiracNotation.jl ├── test │ └── runtests.jl └── .travis.yml
Julia 1.0 が出る前に PkgDev.jl を使ってパッケージを作ったことがある人ならお気付きかもしれませんが、Julia 0.6 時代の構成と変わりません。
野良パッケージの時は必要なかった REQUIRE は必須で、野良パッケージの時に必須の Project.toml はなくても構いません。
(むしろ Project を JuliaCIBot は扱えないから入れないでと私より前に PR を投げていた人は言われていました*4。そんなこととは露知らず私は Project 込みで PR 投げましたが JuliaCIBot のテストも通ったし、特に何か指示されることもありませんでした。
なので結局 Project を入れて良いのか、入れないほうが良いのかよくわかりません。)
以前紹介したパッケージの作り方 に則ってパッケージを作った場合、LICENSE.md, README.md, REQUIRE, .travis.ymlが足りないので追加します。
LICENSE
ライセンスは適宜決めてください。Julia のパッケージの場合 MIT LICENSE を採用しているものが多いです。特にこだわりがない場合は MIT LICENSE にしておけば良いと思います。
ライセンスファイルは Github で
Create new file --> ファイル名に LICENSE と打つと Choose a license template と出るのでクリック --> ライセンスを選ぶ
とすると簡単に作れます。



README
作ったパッケージがどんなパッケージなのか README に軽く書きましょう。
Julia では、公式パッケージに登録する場合レビューが入るので README にどんなパッケージなのかの説明がないとレビュアーが困ってしまいます。
README に使い方を書くか、別枠で使い方のドキュメントをちゃんと作りましょう。 「ドキュメントがないと悲しくなる」と Udacity の人も言っていたので、ドキュメント大事。 www.udacity.com
Travis CI

Julia の公式パッケージに登録する場合は JuliaCIBot *5 のテストは通せなくても Travis を通すのは必須です。 Travis でのテストが失敗すると「テスト失敗してるよ」とツッコミが入ります。
.travis.yml は外部ライブラリ*6に依存していない限り、大体こんな感じに書いておけば良いと思います。
language: julia os: - linux - osx julia: - 0.7 - 1.0 - nightly matrix: allow_failures: - julia: nightly notifications: email: false
テストできる OS は Linux または Mac です。必ずどちらかは入れてください。ここで Windows は使えません。
Julia の項目はパッケージが対応している Julia のバージョンを明示的に書いてください。release と書くと「明示的に書いて」とレビュアーから言われます。
REQUIRE
現状で一番面倒くさいことになっているのが REQUIRE です。Julia 1.0 向けのパッケージなのに Julia 0.x の作法に則らなければなりません。
野良パッケージ作成時に作った Project.toml のようなものなんですが少し違います。
以前の記事では例え標準ライブラリだろうとも Project.toml に書かなければならないと書きましたが、REQUIRE では逆に標準ライブラリを書いてはいけません。
依存している外部パッケージのみ REQUIRE に自力で書いてください。Project.tomlと違って自動で作ってはくれません。
ここいう外部パッケージは公式パッケージに限られます。
今回私が作った DiracNotation.jl の REQUIRE はこんな感じです。
julia 0.7 Requires
julia 0.7 と書くと Julia v0.7 以降の Julia を対象としているという意味になります。Julia 1.0 向けのパッケージだったら v0.7 を対応に入れなくても良いのですが、まだ Julia 1.0 に完全移行できていない人もいると思うので Julia 0.7 も対応に入れておくと良心的かなと思います。v0.7 = v1.0 + deprecation warning なので v0.7 を入れても問題ないはずですし。
外部パッケージの方にも適宜対応しているバージョンを書いてください。
私が初めて METADATA にパッケージを登録した時は「対応している外部パッケージのバージョンも書いて」と言われたのですが、最近はあまり言われていない印象です。レビュアーによってその辺のさじ加減は違うのかなという気はします。
ただ、メジャーバージョンが上がる前のパッケージでしか動かないなどという場合はちゃんと REQUIRE にバージョンも書きましょう。そうしないとそもそも travis で失敗すると思いますが。
対象とするバージョンの詳しい書き方は v0.6 時代のドキュメントを読んでください。
パッケージの名前
公式パッケージにする場合、パッケージの名前にも注意を払う必要が有ります。
とりあえず、
- 略語を入れない
- パッケージ名に Julia という単語を入れない
- アッパーキャメルケースにする (私のパッケージの場合、Diracnotation でなく DiracNotation にする)
ということを守っておけばパッケージ名に関しては何も言われないのではと思います*7。
詳しいことは v0.6 時代のドキュメントを読んでください。
METADATA に PR を投げる
全ての準備は整いました。あとは PR を投げるだけです。 自力で PR を投げる場合、METADATA.jl を fork して編集して・・・ とやるのですが、今は attobot という便利なツールがあるのでこれを使いましょう。むしろ自力で PR を投げると「次回からはattobot使ってね」と言われるので初めから attobot 使いましょう。 attobot を使うと Github 上でバージョンタグを付けると自動で METADATA へ PR を投げてくれます。
https://github.com/integration/attobot にアクセスすると、attobot をまだインストールしていない場合、Install 画面が出ると思うのでインストールしてください。
そのあと、Configure -> Select repositories -> METADATA に PR 投げたいパッケージを選ぶ -> Save


attobot を入れたら Github 上でバージョン番号でタグ付けします。バージョン番号はセマンティック バージョニング に従ってください。以前は初回リリース時は v0.0.1 と付けるのが普通でしたが、最近は v0.1.0 から始めるようです。
タグ付けすると自動的に METADATA.jl へ PR が投げられます。私のような OSS 開発素人は一番緊張するところです。



Publish release をクリックしたら自動的に METADATA.jl に PR が投げられます。こんな感じ。

30秒経っても PR が作られない場合、「PR が作られないのだけれど。。。」と attobot のリポジトリに issue を立ててください。中の人が対応してくれます。
私は一度だけ PR が出来なかったことがあるのですが、その時は Travis が終了する前に PR を投げたのでそのせいなのかなぁと思いました。真相は結局わかっていませんが 。
あとは静かに3日待ちます。投げた PR に3日間コメントがないと自動的にその PR はマージされるらしいです*8 *9。 *10
あなたの PR よりも後に出した PR の方が先にマージされることがありますが文句を言ってはいけません。すでに公式パッケージになっているもののバージョン上げの場合、速攻マージされます。新参者は静かに待ちましょう。
特に問題がなければ以下のようにマージされます。☆-ヽ(*´∀`)八(´∀`*)ノイエーイ

パッケージ名だけで追加できちゃう(σ・ω・)σYO♪
公式パッケージのみに許された特権だ (σ≧∀≦)σчоッ☆

おわりに
いかがだったでしょうか?公式パッケージにするまでの方法の雰囲気はつかめましたでしょうか?
Julia の公式パッケージ作りは全て英語でやりとりしないといけないので、私のような英語が苦手な人にとってはなかなか大変ですが、苦労した分 公式パッケージとしてリリースできたときの達成感は何ものにも代え難いです。
私のような素人 Julian でも出来るのですから、皆さんも気楽に Let's try!!!
パッケージ作りでわからないことがあったら公式の Discourse か Slack で聞いてください。
余談
パッケージを作った当初は公式パッケージにするつもりはなかったのですが、QuantumOptics.jl の gitter にて JuliaDiffEq で有名な Rackauckas さんに私の野良パッケージへのリンクを貼っていただき、まわりの反応もそんなに悪くなさそうだったので公式パッケージにしてもいいかなぁという気になりました。

また、前々から外部パッケージに依存しないパッケージを作りたいなぁと思っていたのと*11、パッケージを Julia 1.0 でも動くように直したら「公式パッケージにしたいなぁ」という謎の衝動に駆られたので公式パッケージとしてリリースすることにしました。
正直に言って pretty-print は自己満足の世界ですし、なくても困らないのでこのパッケージが使われることは殆どないと思いますが、パッケージのリリースアナウンスツイートが Julia 創始者の一人である Viral B. Shah さんからリツイート & いいね をもらえたのでそれだけで私は満足です。
I have released a #julialang package, DiracNotation.jl.
— ゴロピカリ (@goropikari_) September 19, 2018
This package shows a matrix by Dirac notation.https://t.co/C0YTAsavA7 pic.twitter.com/bOAXK3eVod
*1:ここでは METADATA.jl に登録されているパッケージを公式パッケージ、登録されていないパッケージを野良パッケージと呼ぶこととします。
*2:Julian = Julia user
*3:Linux だけ、 または Mac だけで動くパッケージの場合はこの記事の内容で大丈夫ですが、Windowsだけで動くものを登録したい場合はこの記事の内容が通用しません。
*4:Register new package Catsay.jl v0.1.0 by attobot · Pull Request #17687 · JuliaLang/METADATA.jl · GitHub
*5:METADATA に PR 投げた時のみに走るテスト
*6:Juliaのパッケージでなく、C 言語のライブラリとかのこと
*7:代替案を出されることも有ります。
*8:Tag Reinforce.jl v0.1.0 by attobot · Pull Request #18098 · JuliaLang/METADATA.jl · GitHub
*9:Register new package DrawSimpleGraphs.jl v0.1.0 by attobot · Pull Request #18043 · JuliaLang/METADATA.jl · GitHub
*10:私は、この「3日で自動的にマージする」という規則を知らなかったので、「回りの人たちにはレスポンスがあるのに何故私のところには何もないの。。。自分でも謎のパッケージ作ったなという自覚はあるけど、コメントするのも憚られるほど!?」と不安になったのですが、コメントがあると自動マージ機能が無効になるというコメントを見て、「むしろ私のパッケージ優等生じゃん!」と開き直れました。
*11:依存があるとパッケージの読み込みが遅くなるし、メンテナンスが面倒