2020-06-26: あつい‥‥
やったこと
あつい
あつすぎる。
ようやく体調が回復してきたのに暑さでダメになりそう。
ミリシタ
無限にメメントフルコンできんって言ってる。
それはそうとワーキングで野球がはじまった。
野球‥‥ロコ‥‥。うーん。
あと3周年。
面白くなってきた。秋葉行きたい‥‥。
https://milishita-3rdanv.idolmaster.jp/va/
Crystal
マクロのパス(定数・型)の解決がまったくレキシカルに行なわれてないのをどうにかしたい、という気持ちになっている。
正直言うと面倒なんだけど、今やらないまま1.0が出るのは非常にマズいと思うので。
具体的には、すべての場合において「マクロ式中のパスの解決はレキシカルに(書いた場所に準拠して)行う」としたい。
現状こうなっているのはメソッド定義中にマクロ式を書いた場合だけなのだけど、この挙動に準拠したい、ということ。
実際、通常の式でパスの解決はレキシカルに行なわれるので、これは合理的だと思う。
例えば、以下のプログラムの実行結果は:macroでも:runtimeでも:Fooが出力される。
module Foo
A = :Foo
def foo
{% p [:macro, A] %}
p [:runtime, A]
end
end
class Bar
A = :Bar
include Foo
end
Bar.new.foo
一方、これがマクロの場合は、:macroでは:Barと出てコンパイル時にエラーになる。
コンパイル時にエラーになるのはグローバル空間にAが無いので当然なのだけど、マクロの中のマクロ式のパスの解決がinclude先のクラスからになっているのはおかしいんじゃないの? ということ。
module Foo
A = :Foo
macro foo
{% p [:macro, A] %}
p [:runtime, A]
end
end
class Bar
A = :Bar
include Foo
end
Bar.foo
マクロの場合は継承などが絡まると問題になるだけなのだけど、hookの場合はどんなときでも呼び出し対象となったクラスをパスの解決のスコープとするので、さらにややこしい。
これも統一したい。
もちろん、これが直感的で完璧な挙動だとは思っていなくて、人によっては不満はあると思う。
が、現状の全く一貫していないよりは間違いなく良いし、パスの解決についてマクロだけを読めば結果が予測可能できるようになり、よりマクロが堅牢になるはずなので、自分はこの方針でいきたい。
このタイミングでbreakingな挙動を入れることに反対する人もいるかもしれないけど、この変更は本来はバグ修正として行われるべき類のものだし、今このタイミングを逃して1.0になって変更できなくなることが問題。
あと、この変更で壊れるマクロがあるとしたら、継承先とかinclude先で特定の定数/型が宣言されていることを前提にしているわけで、かなり奇妙なケースなのでほとんどありえない、というのが自分の見解。
比較的そういったコードのありそうなORMマッパーのライブラリのコードを確認したりしたけど、実際、無さそうな雰囲気だった。
というような感じのことを明日あたりissueで立てる。