2015-06-25 151 views
3

我知道Crystal在編譯時有它的宏定義代碼的系統,但有可能除此之外運行代碼嗎?在編譯時運行任意代碼

例如,我們可以這樣做,以便它在編譯期間運行?

puts "foobar" 

或者,對於更嚴重的例子,我們可以讀取和寫入運行編譯器的文件系統嗎?

回答

6

是的,我們可以!在run macro methodsystem 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時,您會注意到編譯後的二進制文件的輸出保持不變,但每次重新編譯時都是隨機的。

+3

謝謝,這似乎這樣的伎倆。有點困惑,因爲在'greeting.cr'中的代碼編譯時(或者根本沒有)輸出'puts'輸出,但是我會修改一下並閱讀你給出的鏈接。 –

+2

......我明白了。它返回最終語句的結果而不是輸出。有意義,完美的作品。再次感謝! –

5

作爲Jonne所說的另一個答案,你可以在編譯時使用puts來輸出一些東西,但是在宏內部。例如:

{{ puts "foobar" }}

你會發現,在編譯期間「foobar的」印,但可執行文件不執行任何(與crystal build foo.cr; ./foo嘗試)

當然只是在編譯時輸出東西是不是非常有用,但是當你想快速調試一些宏時它很有用。

puts宏方法記錄在這裏:http://crystal-lang.org/api/Macros.html#puts%28expression%29%3ANop-instance-method

+2

非常好,謝謝! –

+4

'{{debug()}}宏也適用於調試宏。它打印生成的水晶代碼。 '{{puts}}'可以用於在編譯時向開發者輸出消息(例如:棄用消息)。 –