我喜歡eval
在Ruby中,因爲它的工作原理很簡單:如何從Crystal中的字符串變量執行代碼?
eval("puts 7 * 8") # => 56
什麼是eval
的水晶相同呢?我知道,我們可以用宏類似的東西:
macro eval(code)
{{code.id}}
end
eval("puts 7 * 8") # => 56
但是,這不會與運行時的值工作:
a = "yo"
eval("puts #{a}") # => prints nothing
我喜歡eval
在Ruby中,因爲它的工作原理很簡單:如何從Crystal中的字符串變量執行代碼?
eval("puts 7 * 8") # => 56
什麼是eval
的水晶相同呢?我知道,我們可以用宏類似的東西:
macro eval(code)
{{code.id}}
end
eval("puts 7 * 8") # => 56
但是,這不會與運行時的值工作:
a = "yo"
eval("puts #{a}") # => prints nothing
水晶是編譯型語言,而Ruby的解釋。這使得在運行時評估代碼變得更加複雜。
在你的例子中,宏在編譯時被擴展,所以實際上你的程序只是puts 7 * 8
。換句話說,它的工作原理是編譯時知道代碼。
但是,如果您想執行包含在任意字符串中的代碼,則必須調用Crystal編譯器,然後執行生成的可執行文件。這實際上是我們在Crystal單元測試中做的事情。但標準庫中沒有包含「eval」函數,因爲這意味着編譯的程序包含內置的Crystal編譯器,實際上沒有多大意義。
另一個問題是如何傳遞參數並獲取返回值。由於您運行的程序和評估的代碼是不同編譯的結果,因此它們可能具有不同的相同類型的二進制表示。
另一方面,在Ruby中使用eval
通常被認爲是不好的做法,必須儘可能避免。
感謝您的解釋 –
您可以使用[運行宏方法](http://crystal-lang.org/api/Macros.html#run%28filename%2C%20%2Aargs%29%20%3A%20MacroId-instance-method ),但這在罕見的情況下才是好事。我甚至不會在Ruby中使用eval,爲什麼不問你實際想要達到什麼? –