爆速でプリントデバッグするCryingを作ったよ -裏-

By | 2014年12月19日

どういうフローで行き着いたかを聞かれることがあったので、iOS アドベントカレンダー19日目-裏-ということでまとめてみました。

本エントリー
爆速でプリントデバッグするライブラリを作ったよ

Swift 熱があがった

この発表を聞き質問して、なんとなく理解が深まった気がして何かできるのではないかと錯覚を起こしたのがきっかけ。

動機

本エントリーより

println から debugPrintln に書き換えたり、メソッドチェーンの途中で println を挟むのってめんどくさくないですか?

思考フロー

ruby の tapp を知っていたので、それっぽいことをどうやって Swfit で実現すればいいんだろうと思いながら、Array 等から定義へジャンプすると Swift の基本となる関数等の定義が書かれているファイルがあるので、それを読んでなんかいけそうな class とかあったりしないかなと調べ始めました。

AnyObject を拡張すれば…

コンパイルエラーで怒られてしまいます。
Optional と NSObject の拡張はできたけど、Swift のインスタンスだと使えないとか…

Protocol を拡張すれば…

Protocol を拡張したところで、実装がないから無意味。
そもそも Swift で Protocol を拡張できるかどうかは知らない。

全てのクラスを拡張すれば…

これは気合いでどうにかするパターン。
Swift で定義されてるだけならまだどうにか…なる…か…
Swift で書かれたライブラリで定義されてるインスタンスには使えないので、そんなの全てに対応するとか無理。

つまるところ基底クラスのない世界にうちひしがれた

暗礁に乗り上げ NSHipster を徘徊する

というわけで絶望にうちひしがれながら、なんか他の機能でどうにかできないかなと徘徊してると 「Swift Operators 」にいきつきました。

これを見てる時に、一つの疑問がわきました。

prefix や suffix に演算子をつけた状態でもメソッド呼び出しができるのか?

var i:Int = 0
i++.description;

これがきっかけで、演算子として tapp 的なものを新しく定義してやれば実現できるということにいきつきました。

実装

たいしたことしていないのでソースコードをみてください。

TODO

スタックトレースの結果がきたない

[2014-12-19 05:08:45 +0900] hoge
    at _TFFC11CryingTests25CryingCallPoftfixTestCase20testCallPostfixValueFS0_FT_T_u_KT_GSqPSs9AnyObject__ L:89

NSThread.callStackSymbols() を使って表示するようにしてるんですけど、これがとても見にくい。
(lldb) backtrace だとファイル名と行数がとれてるんだけど、これをどうすれば取れるかがイマイチ分かってない。

せめて addr2line 的なことがしたい。

Building assert() in Swift, Part 2: FILE and LINE」とあるけど、演算子だと引数が決められているのでダメ。

C言語の execinfo.h の backtrace でも結果は変わらない。
おそらく callStackSymbols の内部でも同じものを呼んでるのではないかという推測。

だれか分かる人教えてください。

まとめ

演算子を定義することにより、規定クラスがない世界でも生きていける。
とはいえ演算子を定義したりオーバーロードしたりしすぎると、副作用もあるのでご利用は計画的に。

Posted in swift | Tagged