For MRI 1.9+ and Rubinius implementation, Ruby source code is compiled into byte-code, and then that byte-code is interpreted by the VM. I want to know the details of this mechanism when running a Ruby script from command-line using the interpreter.
- Does the interpreter compile all related source files required in the script first and then it run everything? Or does it execute some code and then compile other files while needed in a lazy way?
- If it's the latter (which I suspect), is this process done by file or by a block of code?
- At which point it stops the execution of byte-code and runs the compilation process again?
- Does this process differ from MRI to Rubinius?
For example, if I run "ruby my_main_script.rb", which requires 3 other rb source files (and this files itself do not have any requirement), the possibility I imagine would be:
A: The interpreter parses my_main_script.rb and the 3 files. After parsing then, it compiles all AST trees to byte-code. It then proceeds to run the byte-code using the VM.
B: Ruby parses my_main_script.rb and compiles it into byte-code. It then runs the byte-code. When encountering a call to a method in another files, it first parse and compiles that files and the continues with the execution. If this is the case, I would like to understand this in detail.
C: Ruby parses and compiles some piece of code from my_main_script.rb according to some (unkwnon to me) criteria, it runs that byte-code and then parses-and-compiles another piece when needed. This process and that "when needed" condition detection method is what would be interesting for me to understand.
Update 30/03/16
I wrote this little experiment script to try to check if B is the right answer:
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' only contains the line "puts 'hello'". If B is the right answer, shouldn't the output be the following?
Injecting code...
hello
It just outputs "hello"...