Crystal にはコンパイル時にコードを定義するためのマクロ システムがあることは知っていますが、それとは別にコードを実行することは可能ですか?
たとえば、コンパイル中に実行できるようにすることはできますか?
puts "foobar"
または、より深刻な例として、コンパイラが実行されているファイル システムから読み書きできるでしょうか?
Crystal にはコンパイル時にコードを定義するためのマクロ システムがあることは知っていますが、それとは別にコードを実行することは可能ですか?
たとえば、コンパイル中に実行できるようにすることはできますか?
puts "foobar"
または、より深刻な例として、コンパイラが実行されているファイル システムから読み書きできるでしょうか?
はい、できます!実行マクロ メソッドまたはシステム マクロ メソッドの助けを借りて。
プログラムがビルドされるたびにランダムな挨拶をプログラムにコンパイルする例を見てみましょう:
あいさつ.txt:
Hello
Hey
Hi
greeting.cr:
puts File.read_lines("#{__DIR__}/greetings.txt").sample
グリーター.cr:
puts {{run("./greeting").stringify}}
でコンパイルするとcrystal build greeter.cr
、コンパイルされたバイナリの出力は同じままですが、再コンパイルするたびにランダムになることがわかります。
Jonne が言ったことに対する追加の回答として、コンパイル時に puts を使用して、マクロ内で何かを出力できます。例えば:
{{ puts "foobar" }}
コンパイル中に「foobar」が出力されますが、実行可能ファイルは何もしません (で試してみてくださいcrystal build foo.cr; ./foo
) 。
もちろん、コンパイル時に何かを出力するだけではあまり役に立ちませんが、いくつかのマクロを手早くデバッグしたい場合には便利です。
puts
マクロ メソッドはここに文書化されています: http://crystal-lang.org/api/Macros.html#puts%28expression%29%3ANop-instance-method