我知道Crystal在編譯時有它的宏定義代碼的系統,但有可能除此之外運行代碼嗎?在編譯時運行任意代碼
例如,我們可以這樣做,以便它在編譯期間運行?
puts "foobar"
或者,對於更嚴重的例子,我們可以讀取和寫入運行編譯器的文件系統嗎?
我知道Crystal在編譯時有它的宏定義代碼的系統,但有可能除此之外運行代碼嗎?在編譯時運行任意代碼
例如,我們可以這樣做,以便它在編譯期間運行?
puts "foobar"
或者,對於更嚴重的例子,我們可以讀取和寫入運行編譯器的文件系統嗎?
是的,我們可以!在run macro method或system macro method的幫助下。
我們已經編譯隨機問候到程序每次它是構建一個例子:
greetings.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
非常好,謝謝! –
'{{debug()}}宏也適用於調試宏。它打印生成的水晶代碼。 '{{puts}}'可以用於在編譯時向開發者輸出消息(例如:棄用消息)。 –
謝謝,這似乎這樣的伎倆。有點困惑,因爲在'greeting.cr'中的代碼編譯時(或者根本沒有)輸出'puts'輸出,但是我會修改一下並閱讀你給出的鏈接。 –
......我明白了。它返回最終語句的結果而不是輸出。有意義,完美的作品。再次感謝! –