SwiftのREPLモード(インタプリタ)
SwiftにはREPLモードがあります。
REPLとはプログラムを対話型に実行できる環境のことで、RubyのirbやPythonのipythonみたいなものです。
Swift BlogでREPLについて紹介されていましたので、その内容を転載しておきます。
SwiftのREPLについて
XCode 6.1にはSwiftを試す別の方法として、対話型のREPLを使用することができます。インタプリタ型言語に慣れている開発者はこのコマンドライン環境に満足します。。経験豊富な開発者もいくつかのユニークな機能に気づくでしょう。REPLを実行するには、ターミナル(アプリケーション > ユーティリティにあります)を起動して、プロンプトにOS X Yosemiteでは”swift”、OS X Marvericksでは”xcrun swift”とうてば、Swift REPLモードになります。
Welcome to Swift version 1.1 (swift-600.0.20.0). Type :help for assistance.
1>
Swiftのステートメントを入力するだけでREPLはすぐに実行します。変数や定数の定義のような式の結果は自動的に整形されてその型と一緒に表示されます。コンソール出力は対話型のセッション内で自然になされます。
1> "100".toInt()
$R0: Int? = 100
2> let name = "Katherine"
name: String = "Katherine"
3> println("Hello, \(name)")
Hello, Katherine
式の結果が明示的に何かに代入されていなくても、一行の結果はREPLによって名前を与えられることに注意して下さい。その後に続くステートメントで値を再利用するのにその結果を参照することができます。
4> $R0! + 200
$R1: Int = 300
Swiftのコンパイラは不完全なコードを認識して、必要に応じて追加の入力をプロンプトで促します。コードはXCodeと同様に自動的にインデントされます。例えば関数の始まりでは以下のようになります。
5> func timesTwo() {
6.
新しいステートメントには行番号に>(山かっこ)がつきますが、連続する行のプロンプトは行番号にピリオドをつけます。見るだけで不完全なコードを完成させるよう求められているのが分かります。ここで次の行を入力することができます。
5> func timesTwo() {
6. return value * 2
7. }
ここで注目してほしいことが3つあります。1つ目は6行目でははじめからインデントされていますが、REPLはかっこを閉じるときに自動的にインデントは戻されるということです。2つ目は関数は今回宣言し忘れていたパラメータを参照し、戻り値の型を必要とするということです。パラメータと戻り値の型の両方の宣言と加える必要があります。3つ目は最終行でエンターを押した後では2つ目の問題を修正できないということです。
履歴
コードがコンパイラに送られたときにREPLの履歴に記録されます。ささいなミスは修正することができます。上記の例で不完全な関数宣言の最後でエンターを押したなら次のメッセージが表示されます。
error: use of unresolved identifier 'value'
他の多くの履歴をもつシステムと同じで、プロンプトで上矢印を押すことで最後の入力を呼び出すことができます。REPLは上記の例では三行全てを呼び出して最後の行にカーソルを表示します。次のセクションで解説しますが、このまま間違いを修正するためにコードを編集することができます。
履歴はセッションの間は保持されて、数百コードを記録しています。表示している行の一番上で上矢印を押せばより古い履歴を呼び出し、空の行で下矢印を押せばより新しい履歴を呼び出すことができます。後で理由を説明していますが、下矢印を押したときに表示される空の行は便利です。
複数行の編集
REPLはよくあるラインエディタと同じようにふるまいますが、クラスや関数の宣言でよくあるような複数行の入力を扱うのに便利な機能を備えています。上記の例では最終行でエンターを押す前に上矢印でカーソルを宣言行まで移動することができます。ここで左カーソルを押してパラメータをいれるかっこ開きの直後にカーソルを持っていきます。
5> func timesTwo() {
6. return value * 2
7. }
パラメータ宣言を入力して右矢印でかっこ閉じの後に移動して、戻り値の型を同じように付け加えます。
Type the parameter declaration, press the right arrow to move past the closing parenthesis and add the return type as well:
5> func timesTwo(value: Int) -> Int {
6. return value * 2
7. }
カーソルがブロックの途中にいるときに宣言を完成させるためにエンターを押してはいけません。エンターを押すと改行が挿入されてしまいます。関数やメソッドのボディに行を追加で挿入する場合にはいいですが、ここでは宣言の最後にカーソルを移動します。下矢印を2回押して最後に移動するか、Emacsの命令であるESC >(ESCキーの後に山かっこ閉じキー)を使います。最後の行でエンターを押せば新しい関数宣言がコンパイラに渡されて、その関数を使用できるようになります。
8> timesTwo(21)
$R2: (Int) = 42
ステートメントが完全であるかどうかを自動で判定してくれるので、コードを入力するだけでREPLはほとんどの場合において正しく動作します。しかし、相互に依存する複数の宣言を同時にサブミットする必要があるときがあります。次のコードについて考えてみましょう。
func foo() {
bar()
}
func bar() {
foo()
}
一行一行入力していくと3行目が完成したときに最初の関数をコンパイルしようとします。当然次のようなエラーが出ます。
error: use of unresolved identifier 'bar'
エンターを押したときに自動的に完全かどうかを判定するのを避けるために、一行で両方の関数を宣言してもいいですが、もっといい方法があります。3行目を入力した後に下矢印を押すのです。そうすると4行目ができて、そのまま続きを入力します。2つの宣言は同時にコンパイルされて望んでいた相互再帰という目的を達成することができます。
クイックレファレンス
REPLを始めるのに役立つように、よく使われる編集やナビゲーションキーをまとめておきます。
矢印キー カーソルを上下左右に動かす
Control+F カーソルを一文字右に移動する、右矢印と同じ
Control+B カーソルを一文字左に移動する、左矢印と同じ
Control+N カーソルを次の行の最後に移動する、下矢印と同じ
Control+P カーソルを前の行の最後に移動する、上矢印と同じ
Control+D カーソルのあたっている文字を削除する
Option+Left カーソルを前の単語の先頭に移動する
Option+Right カーソルを次の単語の先頭に移動する
Control+A カーソルを現在の行の先頭に移動する
Control+E カーソルを現在の行の最後に移動する
Delete カーソルの左にある文字を削除する
Esc < カーソルを最初の行の先頭に移動する
Esc > カーソルを最終行の最後に移動する