スイスイSwift!第3回REPLモードとシェルモードでギーク開発
skill

スイスイSwift!第3回
REPLモードとシェルモードでギーク開発

2015.02.05

ent89_img01.jpg

今回はREPL(Read eval print loop)とシェルスクリプトとしてのSwift環境を紹介する。開発環境を整えなくともSwiftの言語と触れ合える2つのモードはテスト環境としてだけでなく実用的なツールとしても活用ができる。もっと気軽に、もっと身近にSwiftを体験できる仕組みを紹介しよう。
繁田 卓二

■ iOS開発関連の動向

本題に入る前にここ最近のiOS開発関連の動向を追っておこう。11月中旬にXcode6.2のベータ版がリリースされた。iOS8.2 SDKが同梱されているこのバージョンでは同時にApple Watchアプリ開発のための環境整備「WatchKit」フレームワークが追加されている。もちろんApple WatchアプリはSwiftでも開発可能である。既に公式サンプルなども上がっており、シミュレータでの動作確認が可能だ。興味のある方はダウンロードしてみると良いだろう。
【WatchKit Catalog: Using WatchKit Interface Elements】
https://developer.apple.com/library/prerelease/ios/samplecode/WKInterfaceCatalog/Introduction/Intro.html#//apple_ref/doc/uid/TP40015046

ent89_img02.jpg

■ REPLモードでのSwift

それでは今回の本題に入ろう。まず、REPLとは「Read eval print loop」の略で、対話的にプログラム命令を受け取り評価する仕組みである。ターミナルなどでpythonコマンドを実行したことがある方はご存知だろう。最近ではWeb上で様々な言語のREPLツールが公開されている。ブラウザ上でREPLが体験できるため、環境構築やツールのインストールは不要だ。例えばrepl.itというサイトでは Javascript、Ruby、Python、Luaなどコードがサイト上で実行できる。REPLがどういうものか、まずは下記サイトで試していただきたい。

【repl.it】
http://repl.it

SwiftにもこのREPLモードが実装されており最新のMac OS X (Yosemite)では標準で搭載されている。こちらはブラウザから使用するものではなく、ターミナルから使用するもので、まるでスクリプト言語であるかのような振る舞いをする。黒い文字ばかりの画面でSwift開発。いかにもギークな開発環境だ。

■ REPLモードの基本操作

REPLモードでのSwiftはOS X Yosemiteクリーンインストール環境で既に用意されている。つまりXcodeや追加のツールをインストールしなくてもSwiftが使用できるのだ。まだ尻込みしているiPhone開発者にとっても、また、これからSwiftを学習しようと思っているが開発環境構築を敬遠している開発者にとっても、より身近に感じられる入り口となるだろう。 その入口は/usr/bin/swiftという一つのコマンドであり、ターミナルから実行することによってREPLモードを開始できる。
アプリケーション → ユーティリティからターミナルを起動し、下記のコマンドを実行しよう。

$ swift [Enter]

Welcome to Swift! Type :help for assistance.

??1>

これだけだ。swiftは既に命令待機状態である。試しに変数mewSoundを宣言してみよう。

??1> let mewSound = “にゃーにゃー“

mewSound: String = “にゃーにゃー“

Enterキーを押すことでその行が即座に評価され次の行に結果が出力される。まさしく「Read」「eval」「print」である。評価は静的解析された結果ではなく、実際に実行された結果となる。つまりファイル操作やネットワーク通信はEnterキーを押した時点で発生する。
REPLでは1ラインでの実行だけでなく複数行での構文も可能だ。次の行で引き続きクラスを定義してみよう。

??2> class Cat {

??3. ????var mewSound = “にゃーにゃー“

??4. ????func mew() -> String {

??5. ???????return self.mewSound

??6. ????}

??7. ?}

??8. let newCat = Cat()

cat: Cat = {

??mewSound =“にゃーにゃー“

}

改行時に文脈を判断し、変数が定義された場合にはその中身がdumpされるようだ。もちろん自分で出力をおこなうこともできる。

??9>?println("\(cat.mew())")

にゃーにゃー

ここまで、評価ごとに出力がおこなわれているが過去に評価された変数やクラスも保持されており同じスコープ上で文脈が継続する。
過去に入力した履歴はカーソルの上キーを押すことでUNIXのコマンドラインの履歴のように参照が可能だ。また、入力中はタブキーでの補完も動作する。単なる辞書による補完でだけでなく、メソッドや型を判断して適切な候補として出してくれる。

??10> newCat[Tabキー]

Available completions:

????.mew() -> String

????.mewSound: String

????newCat: Cat

????(null)

?

??11> :quit

REPLモードを終了するにはコマンド「:quit」もしくは「:q」を入力する。
ショートカットキーControl+Dでも終了は可能だ。

■ フレームワークの追加

REPLモードはそのままではSwiftの基本構文しか使用できない。たとえばNSDateで日付オブジェクトを生成してみよう。

??1> let now = NSDate()

/tmp/lldb/26004/repl1.swift:2:11: error: use of unresolved identifier 'NSDate'

let now = NSDate()

????^

NSDateというクラスが認識できていないようだ。NSString や NSDate などの Foundation フレームワーク由来のクラスを使用するにはimport指示子を使用しフレームワークをインポートする必要がある。

??1> import Foundation

????2> let now = NSDate()

now: NSDate = 2014-11-24 17:24:30 JST

ただし、iOS アプリを開発するための UIKit フレームワークは REPL モードでは使用できない。実行環境が OS X なので当然といえば当然だ。これは今後のバージョンアップでの改善を期待しよう。

■ コマンドラインとしてのSwift

ここまで読んで、REPLの使いどころがあるのか?と疑問に思った方も多いのではないだろうか。

??1> import UIKit

/tmp/lldb/26004/repl16.swift:2:8: error: no such module 'UIKit'

import UIKit

確かに、アプリ開発に使えなくも無いがXcodeを使用したほう格段に効率が良い。せいぜい、ちょっとしたコードの確認や学習用に使用できる程度だろう。しかし今回REPLモードを取り上げた理由はこれだけではない。
REPLモードを開始するswiftコマンド、これ自体はREPLのためだけでなく、インタプリタとしてSwiftのソースコードを直接実行できる。さらにはこれを使用して、シェルスクリプトとしてプログラムを記述し、実用的なコマンドを Mac OS X Yosemite のユーザ同士で共有することができる。シェルスクリプトでできる事といえば、ローカルにある大量ファイルの操作や、リモートデータの収集など、マクロ的な操作の記述が多いが、Swiftだと非同期処理やスレッドを扱った複雑なシェルスクリプトを容易に記述することができる。

通常、シェルスクリプトは1行目にシェバング(shebang)と呼ばれるシェルのパス宣言を記述する。#!/bin/sh や #!/usr/bin/perl などはよく見たことがあるだろう。もう想像はできると思うがSwiftシェルの場合はここに#!/usr/bin/swiftと記述すれば良い。
以下の内容のスクリプトを任意のディレクトリに today.swift というファイル名で保存しよう。

#!/usr/bin/swift

?

import Foundation

?

let today = NSDate()

println("現在時刻は \(today) です")

シェルスクリプトはこのままでは実行できないのでchmodコマンドで実行権限を与えよう。

$ chmod +x today.swift

$ ./today.swift

現在時刻は 2014-11-24 12:05:03 +0000 です

これでシェルスクリプトとして実行可能となる。

■ SwiftシェルからAppKitを使う

前項の通り、UIKitはシェルスクリプトモードでも使用はできない。だが、AppKitを使用することにより、シェルスクリプトからもGUIの操作が可能だ。AppKitはMac OS X向けのUIフレームワークで、UIKitの元になったNSWindow、NSTableView、NSAlertなど、Macアプリで必ず使用されているコンポーネント群を提供する。このUIコンポーネントをシェルスクリプトから使用してみよう。
今回は、アラートダイアログを表示し、OKボタンを押した場合のみGeekroid(仮)のサイトをデフォルトブラウザで開くという簡単なシェルを作成する。NSAlertクラスを定義し、メッセージやボタンをセット。runModal()でモーダル表示し、ボタンを押した結果を受け取り、URLをオープンする、という内容だ。
拡張子を.commandとして保存し、実行権限を与えておくと、ファイルをダブルクリックするだけで実行可能となる。

#!/usr/bin/swift

?

import Foundation

import AppKit

?

let alert = NSAlert()

alert.alertStyle = NSAlertStyle.InformationalAlertStyle

alert.messageText = "Geekroid(仮)のページをブラウザで開きます。よろしいですか?"

alert.addButtonWithTitle("OK")

alert.addButtonWithTitle("Cancel")

let res:Int = alert.runModal()

?

if (res == NSAlertFirstButtonReturn) {

??NSWorkspace.sharedWorkspace().openURL(NSURL(string:

??"http://geekroid.localhost/")!)

}

ent89_img03.jpg

■ まとめ

Mac OSには古くからAppleScriptというマクロ的な言語が搭載されているが、Apple社はSwiftシェルをAppleScriptの置き換えと位置づけているのではないか、と筆者は推測する。Swiftが世に浸透すれば、iOS開発者でなくてもSwiftシェルスクリプトを手軽に開発できMacユーザ同士で共有しあうことができる。iOS開発言語がObjective-Cのままであれば、あり得なかった話である。

原稿:繁田卓二
qnote最高技術責任者。猫とビールをこよなく愛するゆるキャラ系プログラマ。
Webアプリ開発からMacアプリ開発を経て現在はiOSアプリ開発に没頭。弱点はAndroid。

この記事はどうでしたか?

おすすめの記事

キャリアを考える

BACK TO TOP ∧

FOLLOW