Swiftを、RubyやUnderscore.js(Lo-Dash)のように書けるExtensions、ExSwiftとDollar.swiftを紹介します。
Extensionsとは?
Objective-Cで既存のクラス拡張する際に使っていたカテゴリは、SwiftではExtensionsと呼ばれるようになりました。カテゴリと同じようにメソッドのOverrideができます。例えば、Arrayクラスでeachを実装したい場合は、以下のように書いた.swiftファイルをプロジェクト内に配置してください。ファイル名は任意です。
extension Array {
func each(f: (Element) -> ()) {
for e in self {
f(e)
}
}
}
["s", "w", "i", "f", "t", "!"].each { println($0) }
//=> s
//=> w
//=> i
//=> f
//=> t
//=> !
もしくは、コマンドラインからswiftを起動させて、上記のコードをコピペすれば、動きます。
ExSwiftの特徴
Github: pNre/ExSwift
ExSwiftはJavaScript (Lo-Dash, Underscore)とRubyにインスパイアされて開発されたSwift Extensionsです。Swiftの既存クラスをベースに拡張し、functionのOverrideを行う事でRubyやUnderscore.jsライクなメソッドを実装しています。また、OperatorsやSubscriptのOverrideも多く行っています。
Extensionsを導入後は自然にメソッドを呼び出す事ができます。こんな感じ。
ExSwiftのWikiより
5.upTo(7, { println($0) })
/* Prints → */
// → 5
// → 6
// → 7
Int.random(min: 5, max: 10)
// → 6
let array = [5, 1, 0, 10]
array.each { item in println(item) }
/* Prints → */
// 5
// 1
// 0
// 10
let array = ["A", "B", "C", "D"]
array.at(0, 2)
// → ["A", "C"]
Dollar.$wiftの特徴
Github: ankurp/Dollar.swift
Dollar.swift(GithubにはDollar.$wiftとも書いてある)を導入すると、Underscore.js(やLo-Dash)由来のメソッドをSwiftで使えるようになります。ExSwiftが既存クラスへの拡張を大胆に行っていたのと対照的に、 Dollar.swiftは __全て$クラスのfunctionとして実装__されています。Swiftの既存クラスは全く拡張していません。
Dollar.swiftが独自のクラス実装した理由は Appleの仕様変更によって挙動が変更されることを避けるため です。よって、呼び出し方はとても特徴的で、$クラスからクラスメソッドを呼び出します。JQueryみたい。
Dollar.swiftのREADME.mdより
$.first([1, 2, 3, 4])
=> 1
$.contains([1, 2, 3, 1, 2, 3], value: 2)
=> true
$.indexOf([3, 4, 5], value: 5)
=> 2
$.range(4)
=> [0, 1, 2, 3]
まとめ
- ExSwiftは既存クラスを拡張している。メソッド呼び出しは自然に行える一方で、 他Extensionsとのコンフリクトの可能性 がある。
- Dollar.swiftは既存クラスには手を入れず、独自クラスのfunciontで実装している。呼び出しは$を使わなければいけないが、 他Extensionsとのコンフリクトは無い。
実際、自分のプロジェクトにExSwiftを導入したのですが、コンフリクトが起こってコンパイルエラーになりました。だいたい、eachやらString[]のsubscriptはみんな拡張するんですよね。なので、ExSwiftを入れるならプロジェクト開始時が良いですね。
今回はExSwiftとDollar.swiftの概要を紹介しました。どちらも盛んに開発されていて、毎日コミットが行われています。ExSwiftのバグをたまたま見つけたのでissueとして登録しましたが、次の日には修正されてました。方針の全く違うExSwiftとDollar.swiftですが、今後どうなるか楽しみです。