对于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
谢谢,这是完美的! –