Julia REPL

Julia の実行形式 julia にはコマンドラインから使えるフル機能の対話 REPL (read-eval-print loop) が組み込まれています。Julia の文を素早く簡単に評価できるのに加えて、この REPL は検索可能な履歴・タブ補完・たくさんの便利なキーバインド・専用のヘルプモードとシェルモードを持ちます。

julia を引数を付けずに呼び出すか、実行形式をダブルクリックすると REPL が起動します:

$ julia

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.5.4 (2021-03-11)
 _/ |\__'_|_|_|\__'_|  |
|__/                   |


julia>

REPL はバナーと julia> というプロンプトを表示します。対話セッションを終了するには ^D とタイプする (空行で Ctrl キーと d キーを同時に押す) か exit() と入力してからエンター/リターンキーを押してください。

プロンプトのモード

Julian モード

Julia REPL は大きく分けて四つの動作モードを持ちます。一つ目の最もよく使われるモードは Julian モードです。これはデフォルトの動作モードであり、julia> で始まるプロンプトがユーザーからの Julia 式の入力を待ちます。完全な式を入力してリターン/エンターキーを押すと、入力内容が評価されてその値が表示されます:

julia> string(1 + 2)
"3"

対話処理でのみ使える便利な機能は他にもたくさんあります。例えば REPL は入力された式の評価結果を表示するのに加えて、その結果を ans という変数に束縛します。また行末にセミコロンを付けると、結果を出力しないフラグが設定されます:

julia> string(3 * 4);

julia> ans
"12"

Julian モードはプロンプトペースト (prompt pasting) と呼ばれる機能をサポートします。これは julia> で始まるテキストを REPL にペーストしたときに有効になる機能であり、このとき julia> 以降の式だけがパースされて他の部分は無視されます。この機能により、プロンプトと出力を削除することなくコードブロックを REPL にコピーできるようになります。デフォルトでこの機能は有効化されていますが、REPL.enable_promptpaste(::Bool) を使えば有効化/無効化が可能です。有効化している状態でこの段落の上にあるコードブロックを REPL に直接ペーストすればプロンプトペーストを試すことができます。なお Windows 標準のコマンドプロンプトではペーストの発生を検出できないので、 この機能は利用できません。

オブジェクトを REPL に表示するときは show 関数が特定の IOContext と共に使われます。具体的に言うと、その IOContext:limit 属性は true で、他の属性 (:compact など) は設定されていなければそれぞれの show メソッドでデフォルト値を受け取ります。実験的な機能として、REPL で使われる IOContext の属性を辞書 Base.active_repl.options.iocontext で設定できるようになっています:

julia> rand(2, 2)
2×2 Array{Float64,2}:
 0.8833    0.329197
 0.719708  0.59114

julia> show(IOContext(stdout, :compact => false), "text/plain", rand(2, 2))
 0.43540323669187075  0.15759787870609387
 0.2540832269192739   0.4597637838786053
julia> Base.active_repl.options.iocontext[:compact] = false;

julia> rand(2, 2)
2×2 Array{Float64,2}:
 0.2083967319174056  0.13330606013126012
 0.6244375177790158  0.9777957560761545

REPL の開始時にこの辞書の値を自動的に定義したいなら、~/.julia/config/startup.jl ファイルで atreplinit 関数を使うと行えます:

atreplinit() do repl
    repl.options.iocontext[:compact] = false
end

ヘルプモード

Julian モードでプロンプトに何も入力していない状態で ? を入力すると、プロンプトがヘルプモードに切り替わります。ヘルプモードの Julia REPL は入力されたテキストに対するヘルプあるいはドキュメントの表示を試みます:

julia> ? # ? をタイプすると、プロンプトがその場で help?> に切り替わる。

help?> string
search: string String Cstring Cwstring RevString randstring bytestring SubString

  string(xs...)

  Create a string from any values using the print function.

マクロ・型・変数も入力できます:

help?> @time
  @time

  A macro to execute an expression, printing the time it took to execute, the number of allocations,
  and the total number of bytes its execution caused to be allocated, before returning the value of the
  expression.

  See also @timev, @timed, @elapsed, and @allocated.

help?> Int32
search: Int32 UInt32

  Int32 <: Signed

  32-bit signed integer type.

行頭でバックスペースを入力するとヘルプモードを終了できます。

シェルモード

ヘルプモードが提供するのはドキュメントへのアクセスですが、もう一つよく実行されるタスクにシステムシェルを使ったシステムコマンドの実行があります。Julian モードのプロンプトの先頭で ? を入力するとヘルプモードに切り替わるのと同様に、セミコロン (;) を入力するとシェルモードに切り替わります。行頭でバックスペースを入力すればシェルモードを抜けます。

julia> ; # ; をタイプすると、プロンプトがその場で shell> に切り替わる。

shell> echo hello
hello
情報

Windows では、Julia のシェルモードから Windows のシェルコマンドにアクセスできません。そのため次のコマンドはエラーになります:

julia> ; # ; をタイプすると、プロンプトがその場で shell> に切り替わる。

shell> dir
ERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)
Stacktrace!
.......

一方で PowerShell へのアクセスの取得は可能です:

julia> ; # ; をタイプすると、プロンプトがその場で shell> に切り替わる。

shell> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\elm>

cmd.exe へのアクセスも可能です。dir コマンドに注目してください:

julia> ; # ; をタイプすると、プロンプトがその場で shell> に切り替わる。

shell> cmd
Microsoft Windows [version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\elm>dir
 Volume in drive C has no label
 Volume Serial Number is 1643-0CD7
  Directory of C:\Users\elm

29/01/2020  22:15    <DIR>          .
29/01/2020  22:15    <DIR>          ..
02/02/2020  08:06    <DIR>          .atom

検索モード

これまでの三つのモードで実行された入力は履歴ファイルに保存されるので、検索が可能です。 ^R とタイプする (Ctrl キーと r キーを同時に押す) とインクリメンタルな履歴の検索が開始されます。プロンプトが (reverse-i-search)`': に切り替わり、文字を入力するたびに検索クエリがクオートの間に表示されます。クエリにマッチした中で最も最近の結果がコロンの右側に表示され、結果は文字を入力する動的に更新されます。現在のクエリに対するもっと古い結果を検索するには、もう一度 ^R をタイプしてください。

^R は後方検索ですが、^S だと前方検索になります。このときのプロンプトは (i-search)`': です。この二つのキーはマッチ結果を前後 (^S/^R) に移動するために利用できます。

キーバインド

Julia REPL には便利なキーバインドが用意されます。Ctrl キーを使ったキーバインドはこれまでにもいくつか (REPL を終了する ^D, 検索を行う ^R^S を) 紹介しましたが、他にも多く存在します。またメタキーを使ったキーバインドもあります。メタキーがどのキーに対応するかはプラットフォームによって異なりますが、たいていのターミナルでは Alt キーまたは Option キーを押した状態で別のキーを押す、あるいは Esc を押して一度指を離してから別のキーを押すことでメタキーを送信する振る舞いがデフォルトとなっています (あるいはそう設定できます)。

キーバインド 説明
プログラムの制御
^D (バッファが空のとき) REPL を終了する。
^C 実行を停止またはキャンセルする。
^L コンソール画面をクリアする。
リターン/エンターまたは ^J 入力を改行 (入力が完全な式なら実行) する。
meta-リターン/エンター 実行せずに改行する。
? または ; (行頭で) ヘルプモードまたはシェルモードに切り替える。
^R, ^S インクリメンタルな履歴検索を行う (前述)。
カーソルの移動
, ^F 一文字右に移動する。
, ^B 一文字左に移動する。
Ctrl-→, meta-F 一単語右に移動する。
Ctrl-←, meta-B 一単語左に移動する。
Home, ^A 行頭に移動する。
End, ^E 行末に移動する。
, ^P 一行上に移動する (またはカーソルより前の部分にマッチする現在より前の履歴エントリーに移動する)。
, ^N 一行下に移動する (またはカーソルより前の部分にマッチする現在より後の履歴エントリーに移動する)。
シフト-矢印 領域選択を有効にした ("シフト選択" した) 状態で矢印キーの方向にカーソルを動かす。
page-up, meta-P 一つ前の履歴エントリーに移動する。
page-down, meta-N 一つ後の履歴エントリーに移動する。
meta-< 最初の履歴エントリーに移動する (現在のセッション開始時点の最初の履歴エントリーが現在位置より前なら、そこに移動する)。
meta-> 最後の履歴エントリーに移動する。
^-Space 編集領域内に "印" を付ける (領域がアクティブなら非アクティブ化する)。
^-Space ^-Space 編集領域に "印" を付け、領域を "アクティブ" にする (ハイライトする)。
^G 領域を非アクティブ化する (ハイライトを消す)。
^X^X 現在位置を印と入れ替える。
編集
バックスペース, ^H 直前の文字あるいはアクティブな領域を削除する。
デリート, ^D 直後の文字を (存在するなら) 削除する。
meta-バックスペース 直前の単語を削除する。
meta-d 直後の単語を削除する。
^W 一番近い空白まで前に向かって入力を削除する。
meta-w 現在の領域をキルリングにコピーする。
meta-W 現在の領域を "キル" してキルリングに送る。
^K 入力を行末まで "キル" してキルリングに送る。
^Y キルリングのテキストを挿入する ("ヤンク")。
meta-y 直前にヤンクされたテキストをキルリングの古いエントリーで置き換える。
^T カーソルの前後にある文字を入れ替える。
meta-↑ 現在の行を上の行と入れ替える。
meta-↓ 現在の行を下の行と入れ替える。
meta-u 次の語を大文字にする。
meta-c 次の語をタイトルケースにする。
meta-l 次の語を小文字にする。
^/, ^_ 最後の編集操作を取り消す。
^Q REPL に数字を書いて ^Q を押すと、対応するスタックフレームまたはメソッドがエディタで開かれる
meta-← 現在の行を左にインデントする。
meta-→ 現在の行を右にインデントする。
meta-. 直前の履歴エントリーの最後の単語を挿入する。

キーバインドのカスタマイズ

Julia REPL のキーバインドは REPL.setup_interface に辞書を渡すことでユーザーから自由に全てカスタマイズできます。このカスタムキーマップを定義する辞書のキーは文字あるいは文字列です。'*' というキーのバリューはデフォルトの操作であり、Ctrl と x のバインドは "^x" で表され、メタキーと x のバインドは "\\M-x" または \ex で表されます。この辞書のバリューは nothing (入力を無視する) か、(PromptState, AbstractREPL, Char) を受け取る関数です。REPL.setup_interface 関数は atreplinit で登録することで REPL が初期化される前に呼び出す必要があります。例えば上下の矢印キーでカーソルより前の部分に対する検索を行わずに履歴を移動するには、次のコードを ~/.julia/config/startup.jl に書き込みます:

import REPL
import REPL.LineEdit

const mykeys = Dict{Any,Any}(
    # 上矢印
    "\e[A" => (s,o...)->(LineEdit.edit_move_up(s)
                        || LineEdit.history_prev(s, LineEdit.mode(s).hist)),
    # 下矢印
    "\e[B" => (s,o...)->(LineEdit.edit_move_down(s)
                         || LineEdit.history_next(s, LineEdit.mode(s).hist))
)

function customize_keys(repl)
    repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)
end

atreplinit(customize_keys)

キー入力に対して利用可能な操作は LineEdit.jl で見ることができます。

タブ補完

Julia REPL の Julian モードとヘルプモードの両方において、関数や型の最初の数文字を入力してから TAB キーを押すとマッチする名前が表示されます:

julia> stri[TAB]
stride     strides     string      strip

julia> Stri[TAB]
StridedArray    StridedMatrix    StridedVecOrMat  StridedVector    String

TAB キーは数学記号を表す LaTeX コマンド文字列を対応する Unicode 文字に置き換えるときにも使えます。このときもマッチする LaTeX コマンド文字列からなるリストが表示されます:

julia> \pi[TAB]
julia> π
π = 3.1415926535897...

julia> e\_1[TAB] = [1,0]
julia> e₁ = [1,0]
2-element Array{Int64,1}:
 1
 0

julia> e\^1[TAB] = [1 0]
julia>  = [1 0]
1×2 Array{Int64,2}:
 1  0

julia> \sqrt[TAB]2     # √ は sqrt 関数と等価
julia> 2
1.4142135623730951

julia> \hbar[TAB](h) = h / 2\pi[TAB]
julia> ħ(h) = h / 2π
ħ (generic function with 1 method)

julia> \h[TAB]
\hat              \hermitconjmatrix  \hkswarow          \hrectangle
\hatapprox        \hexagon           \hookleftarrow     \hrectangleblack
\hbar             \hexagonblack      \hookrightarrow    \hslash
\heartsuit        \hksearow          \house             \hspace

julia> α="\alpha[TAB]"   # LaTeX 補完は文字列の中でも動作する。
julia> α="α"

タブ補完の完全なリストはマニュアルの Unicode の入力の章にあります。

Julia REPL のシェルモードおよび文字列ではパスの補完が働きます:

julia> path="/[TAB]"
.dockerenv  .juliabox/   boot/        etc/         lib/         media/       opt/         root/        sbin/        sys/         usr/
.dockerinit bin/         dev/         home/        lib64/       mnt/         proc/        run/         srv/         tmp/         var/
shell> /[TAB]
.dockerenv  .juliabox/   boot/        etc/         lib/         media/       opt/         root/        sbin/        sys/         usr/
.dockerinit bin/         dev/         home/        lib64/       mnt/         proc/        run/         srv/         tmp/         var/

タブ補完で入力引数に対して利用可能なメソッドの一覧を取得することもできます:

julia> max([TAB] # メソッドが全て表示される (長いのでここでは省略)。

julia> max([1, 2], [TAB] # 第一引数が Vector{Int} にマッチする全てのメソッドが表示される。
max(x, y) in Base at operators.jl:215
max(a, b, c, xs...) in Base at operators.jl:281

julia> max([1, 2], max(1, 2), [TAB] # ここまでの引数にマッチする全てのメソッドが表示される。
max(x, y) in Base at operators.jl:215
max(a, b, c, xs...) in Base at operators.jl:281

メソッドに対するマッチでは ; の後ろにキーワード引数も表示されます。次の例では limitkeepempty がキーワード引数です:

julia> split("1 1 1", [TAB]
split(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302
split(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277

メソッドの補完は型推論を使うので、引数が他の関数の出力であっても正しくマッチを判定できます。マッチしないメソッドを補完から取り除くには、引数に含まれる関数呼び出しが型安定である必要があります。

タブ補完はフィールドの補完にも使えます:

julia> import UUIDs

julia> UUIDs.uuid[TAB]
uuid1        uuid4         uuid_version

関数の返り値のフィールドも補完できます:

julia> split("","")[1].[TAB]
lastindex  offset  string

関数の返り値に対するフィールドの補間は型推論を使うので、関数が型安定なときにだけ利用できます。

辞書のキーもタブ補完できます:

julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3)
Dict{String,Int64} with 3 entries:
  "qwer2" => 2
  "asdf"  => 3
  "qwer1" => 1

julia> foo["q[TAB]

"qwer1" "qwer2"
julia> foo["qwer

色のカスタマイズ

Julia と REPL が利用する色もカスタマイズできます。Julia プロンプトの色を変えるには、ホームディレクトリの ~/.julia/config/startup.jl に次のようなコードを追加してください:

function customize_colors(repl)
    repl.prompt_color = Base.text_colors[:cyan]
end

atreplinit(customize_colors)

利用可能な色は REPL のヘルプモードで Base.text_colors を参照すれば確認できます。色を表すシンボル以外にも、256 色サポートのあるターミナルでは 0 から 255 までの整数を使った色の指定も可能です。

同様にヘルププロンプト・シェルプロンプト・入力テキスト・出力テキストを変更するには、上記の customize_colors 関数で repl の対応するフィールド (help_color, shell_color, input_color, answer_color) を変更します。最後の二つのフィールドを変更するときは envcolors フィールドを false にするようにしてください。

色として Base.text_colors[:bold] を使えば太字にできます。例えば出力を太字にするには次のようにします:

function customize_colors(repl)
    repl.envcolors = false
    repl.answer_color = Base.text_colors[:bold]
end

atreplinit(customize_colors)

警告や情報のメッセージで使われる色は対応する環境変数で変更できます。例えばエラー・警告・情報メッセージをそれぞれマゼンタ・黄色・シアンにするには、~/.julia/config/startup.jl に次のコードを追加します:

ENV["JULIA_ERROR_COLOR"] = :magenta
ENV["JULIA_WARN_COLOR"] = :yellow
ENV["JULIA_INFO_COLOR"] = :cyan

TerminalMenus

TerminalMenus は Julia REPL のサブモジュールであり、小さい簡単なメニューをターミナルに提供します。この節では次のリストをメニューの選択肢として使います:

import REPL
using REPL.TerminalMenus

options = ["apple", "orange", "grape", "strawberry",
            "blueberry", "peach", "lemon", "lime"]

RadioMenu

RadioMenu はユーザーにリストから要素を一つ選択させます。request 関数を呼ぶと対話メニューが表示され、ユーザーが選択した要素の添え字が返ります。ユーザーが q または Ctrl-c を押すと、request-1 を返します。

# pagesize は一度に表示される要素数を表す。
# 選択肢の数が pagesize より多いと、UI はスクロールする。
menu = RadioMenu(options, pagesize=4)

# request を実行するとメニューが表示され、
# ユーザーが要素を選択すると返る。
choice = request("Choose your favorite fruit:", menu)

if choice != -1
    println("Your favorite fruit is ", options[choice], "!")
else
    println("Menu canceled.")
end

出力は次の通りです:

Choose your favorite fruit:
^  grape
   strawberry
 > blueberry
v  peach
Your favorite fruit is blueberry!

MultiSelectMenu

MultiSelectMenu はユーザーにリストから複数の要素を選択させます。

# デフォルトの pagesize (10) を使う。
menu = MultiSelectMenu(options)

# request は選択された添え字からなる Set を返す。
# Ctrl-c または q でメニューがキャンセルされると空の Set が返る。
choices = request("Select the fruits you like:", menu)

if length(choices) > 0
    println("You like the following fruits:")
    for i in choices
        println("  - ", options[i])
    end
else
    println("Menu canceled.")
end

出力は次の通りです:

Select the fruits you like:
[press: d=done, a=all, n=none]
   [ ] apple
 > [X] orange
   [X] grape
   [ ] strawberry
   [ ] blueberry
   [X] peach
   [ ] lemon
   [ ] lime
You like the following fruits:
  - orange
  - grape
  - peach

カスタマイズ/設定

TerminalMenu インターフェースのカスタマイズは TerminalMenus.config() で行います。この関数はキーワード引数だけを受け取ります。

引数

julia> menu = MultiSelectMenu(options, pagesize=5);

julia> request(menu) # デフォルトは ASCII
[press: d=done, a=all, n=none]
   [ ] apple
   [X] orange
   [ ] grape
 > [X] strawberry
v  [ ] blueberry
Set([4, 2])

julia> TerminalMenus.config(charset=:unicode)

julia> request(menu)
[press: d=done, a=all, n=none]
    apple
    orange
    grape
   strawberry
   blueberry
Set([4, 2])

julia> TerminalMenus.config(checked="YEP!", unchecked="NOPE", cursor='⧐')

julia> request(menu)
[press: d=done, a=all, n=none]
   NOPE apple
   YEP! orange
   NOPE grape
  YEP! strawberry
  NOPE blueberry
Set([4, 2])

リファレンス

Base.atreplinit ── 関数

atreplinit(f)

対話セッションで REPL インターフェースが初期化される前に呼ばれる関数として一引数の関数 f を登録します。f には REPL オブジェクトが引数として渡されます。atreplinit は初期化ファイル .julia/config/startup.jl から呼ばれるべきです。

広告