Avatar
Avatar
rintaro
@Kishikawa Katsumi PowerAssert って現状ざっくり PowerAssert.Assertion("foo.bar(baz)") .assert(foo.bar.baz()) .capture(expression: foo.bar(baz), column: 4) .capture(expression: foo, column: 0) .captuer(expression: baz, column: 8) みたいに展開するとおもうんですが、下みたいにしたら、副作用ある式でも対応できて評価が一回で済むかなと思ったのですが、 PowerAssert.Assertion("foo.bar(baz)") { (values: inout [Value]) throws -> Bool in func _capture<T>(_ expr: @autoclosure () throws -> T, column: Int) rethrows -> T { let val = try expr() values.append(Value(value: _toString(val), column: column)) return val } return try _capture(_capture(foo, column: 0).bar(_capture(baz, column: 8)), column: 4) } なにか落とし穴あります? (edited)
Kishikawa Katsumi 4/10/2023 1:32 AM
https://github.com/kishikawakatsumi/swift-power-assert/pull/9 やってみました。いくつか元の処理だとできてた部分がうまく動かない部分がまだあるのですが逆に今まで無理してた部分が自然になったところも多いのと、コード生成の処理がかなりシンプルになったのでこちらの方が良さそうです。現状うまくいかなくない部分も調整すればたぶん解決できそう。 Positive: コード生成の処理が簡単になった。 Positive: 評価が一回になったので副作用のある式でもダンプした値と実際の値が一致するようになった。 Positive: "...".data(using: .utf8)).utf8のような独立して評価すると型情報が足りないような式も全体で評価できるから型推論が効いてしてコンパイルできるようになった。 capture("...").data(using: capture(.utf8))みたいなコード生成になってコンパイルできる。 Positive: SyntaxRewriterを使って〜〜ExprSyntaxを対象にする、としたので今までのコードパターンから考えるやり方よりシステマチックにできるようになった。 Neutral: 動作したときに評価されなかった値はそもそも実行されないので出力されない。 (例)三項演算子の片方、|| で短絡評価された場合の残りの式など。 (edited)
Changed to a code generation that does not affect the evaluation of expressions containing side effects. Before: PowerAssert.Assertion("foo.bar(baz)") .assert(foo.bar.baz()) .capture(...