對於MRI 1.9+和Rubinius實現,Ruby源代碼被編譯爲字節碼,然後該VM解釋該字節碼。在使用解釋器從命令行運行Ruby腳本時,我想知道這個機制的細節。Ruby解釋器是否以懶惰的方式編譯爲字節碼?怎麼樣?
- 解釋器是否先編譯腳本中所需的所有相關源文件,然後運行一切?還是執行一些代碼,然後在需要時以一種懶惰的方式編譯其他文件?
- 如果是後者(我懷疑),這個過程是通過文件還是通過一段代碼完成的?
- 在哪一點停止執行字節碼並再次運行編譯過程?
- 這個過程是否與MRI到Rubinius不同?
例如,如果我跑「紅寶石my_main_script.rb」,這需要其他3個RB源文件(這個文件本身沒有任何要求),我想象中的可能性是:
A:解釋器解析my_main_script.rb和3個文件。然後解析後,它將所有AST樹編譯爲字節碼。然後它繼續使用VM運行字節碼。
B:Ruby解析my_main_script.rb並將其編譯爲字節碼。然後它運行字節碼。當遇到對另一個文件中某個方法的調用時,它首先解析並編譯該文件,並繼續執行。如果是這種情況,我想詳細瞭解這一點。
Ç:紅寶石解析和編譯根據一些從一些my_main_script.rb一段代碼(unkwnon我)的標準,它運行的字節碼,然後解析和 - 編譯需要時的另一塊。這個過程和「需要時」狀態檢測方法是我理解的有趣的東西。
更新30/03/16
我寫了這個小實驗的腳本來嘗試檢查,如果B是正確答案:
class RubyVM
class InstructionSequence
class << self
alias :old_compile_file :compile_file
def compile_file(code, opt)
puts "Injecting code..."
old_compile_file(code, opt)
end
alias :old_compile :compile
def compile(code)
puts "Injecting code..."
old_compile(code)
end
end
end
end
require_relative 'say_hi'
「say_hi.rb '只包含行'puts'hello'「。 如果B是正確的答案,不應該輸出以下內容?
Injecting code...
hello
它只是輸出 「你好」 ......
你能提供一個示例腳本,然後解釋如何該腳本會在不同的兩種理論來執行?就像,如果「解釋程序先編譯腳本中所需的所有相關源文件,然後運行所有內容」,那麼結果如何?如果「它執行一些代碼,然後同時需要一個懶惰的方式編譯其他文件」,將是什麼樣子? –
@kitkat完成!希望它有幫助 – lucianolev
謝謝,這是完美的! –