Swift 5.0 日本語化計画 : Swift 5.0
ブログ:Swift パッケージ用の REPL サポート
2018年10月8日 Ankit Aggarwal
swift run コマンドには、パッケージのライブラリターゲットのインポートをサポートする Swift REPL を起動する新しい --repl オプションがあります。
Swift 言語には Swift の配布と共に REPL が付属しています。Swift REPL は、使い捨ての Swift パッケージまたは Xcode プロジェクトを作成することなく Swift コードを試すための素晴らしいツールです。REPL は、引数なしで swift コマンドを実行すると起動できます。
Swift REPL を使用すると、Foundation、Dispatch などのコアライブラリ、macOS 上の Darwin や Linux の Glibc などのシステムモジュールを実際に、REPL は、REPL を起動している間に提供されるコンパイラ引数を使用して適切に検索してロードできる限り、インポートできます。Swift パッケージマネージャーはこの機能を利用し、パッケージのライブラリターゲットをインポートするために必要なコンパイラ引数を使用して REPL を起動します。
例
いくつかの例を使って新しい機能を探ってみましょう:
Yams
(ここをクリックすると GitHub にリンクします)Yams は YAML を扱うための Swift パッケージです。
swift run --repl を使用してパッケージをクローンし、REPL を起動します:
$ git clone https://github.com/jpsim/Yams $ cd Yams $ swift run --repl
これによりパッケージがコンパイルされ、Swift REPL が起動されます。オブジェクトを YAML に変換する dump メソッドを使ってみましょう:
1> import Yams 2> let yaml = try Yams.dump(object: ["foo": [1, 2, 3, 4], "bar": 3]) yaml: String = "bar: 3\nfoo:\n- 1\n- 2\n- 3\n- 4\n" 3> print(yaml) bar: 3 foo: - 1 - 2 - 3 - 4
同様に、load メソッドを使って文字列をオブジェクトに変換して戻すことができます:
4> let object = try Yams.load(yaml: yaml) object: Any? = 2 key/value pairs { ... } 5> print(object) Optional([AnyHashable("bar"): 3, AnyHashable("foo"): [1, 2, 3, 4]])
Vapor’s HTTP
Vapor (蒸発する) プロジェクトには、SwiftNIO パッケージの上に構築された HTTP パッケージがあります。
swift run --repl を使用してパッケージをクローンし、REPL を起動します:
$ git clone https://github.com/vapor/http $ cd http $ swift run --repl
HTTPClient 型を使用して GET リクエストを作成しましょう:
1> import HTTP 2> let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1) 3> let client = HTTPClient.connect(hostname: "httpbin.org", on: worker).wait() 4> let httpReq = HTTPRequest(method: .GET, url: "/json") 5> let httpRes = try client.send(httpReq).wait() 6> print(httpRes) HTTP/1.1 200 OK Connection: keep-alive Server: gunicorn/19.9.0 Date: Sun, 30 Sep 2018 21:30:41 GMT Content-Type: application/json Content-Length: 429 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true Via: 1.1 vegur { "slideshow": { "author": "Yours Truly", "date": "date of publication", "slides": [ { "title": "Wake up to WonderWidgets!", "type": "all" }, { "items": [ "Why <em>WonderWidgets</em> are great", "Who <em>buys</em> WonderWidgets" ], "title": "Overview", "type": "all" } ], "title": "Sample Slide Show" } }
Foundation の JSONSerialization を使用して反応を解析できます。
7> let result = try JSONSerialization.jsonObject(with: httpRes.body.data!) as! NSDictionary result: NSDictionary = 1 key/value pair { [0] = { key = "slideshow" value = 4 key/value pairs { [0] = { key = "slides" value = 2 elements } [1] = { key = "author" value = "Yours Truly" } [2] = { key = "title" value = "Sample Slide Show" } [3] = { key = "date" value = "date of publication" } } } }
実装の詳細
Swift パッケージで REPL を使用するには、REPL 引数を構成するために 2 つの情報が必要です。最初の部分は、ライブラリターゲットとその依存関係のヘッダ検索パスを提供しています。Swift ターゲットの場合、これはモジュールの .swiftmodule ファイルへのパスを提供することを意味し、C ターゲットの場合は、ターゲットのモジュールマップファイルを含むディレクトリのパスが必要です。2 番目の部分は、すべてのライブラリターゲットの全てを含む共有動的ライブラリを構築しています。これにより、REPL は実行時に必要なシンボルをロードすることができます。SwiftPM は、ルートパッケージのすべてのライブラリターゲットを含む特別なプロダクトを合成することでこれを行います。この特別なプロダクトは、--repl オプションを使用する場合にのみビルドされ、他のパッケージマネージャーの操作には影響しません。
完全な実装の詳細については、この機能を実装した プルリクエスト をチェックしてください。
結論
Swift パッケージの REPL サポートにより、REPL 環境がさらに強化され、ライブラリパッケージの作者および読者にとってより簡単な実験が可能になります。この機能は、最新の基幹の スナップショットで試すことができます。バグを発見した場合や強化リクエストがある場合は、JIRA に提出してください!
質問?
質問があり、もっと学びたい場合は、Swift フォーラム内の関連 ディスカッションスレッド をご覧ください。