Для реализации MRI 1.9+ и Rubinius исходный код Ruby скомпилирован в байт-код, а затем этот байт-код интерпретируется виртуальной машиной. Я хочу узнать подробности этого механизма при запуске Ruby-скрипта из командной строки с использованием интерпретатора.Является ли интерпретатор Ruby компиляцией байтового кода ленивым способом? Как?
- Содержит ли интерпретатор все связанные исходные файлы, необходимые для первого скрипта, а затем запускает все? Или он выполняет какой-то код, а затем компилирует другие файлы, когда он нужен ленивым способом?
- Если это последний (что я подозреваю), этот процесс выполняется файлом или блоком кода?
- В какой момент он останавливает выполнение байтового кода и снова запускает процесс компиляции?
- Отличается ли этот процесс от МРТ до Рубиния?
Например, если я бегу «рубиновый my_main_script.rb», который требует 3 других гь исходных файлов (и эти файлы сами по себе не имеют каких-либо требований), возможность я полагаю, было бы:
A: интерпретатор анализирует my_main_script.rb и 3 файла. После синтаксического анализа он компилирует все деревья AST в байт-код. Затем он запускает байт-код с использованием виртуальной машины.
B: Ruby разбирает my_main_script.rb и скомпилирует его в байтовый код. Затем он запускает байт-код. Когда вы сталкиваетесь с вызовом метода в других файлах, он сначала анализирует и компилирует эти файлы и продолжает выполнение. Если это так, я хотел бы разобраться в этом подробно.
C: Ruby разбирает и собирает некоторую часть кода из my_main_script.rb согласно некоторым (unkwnon мне) критерии, он запускает этот байт-код, а затем разбирает-и-компилирует другую часть, когда это необходимо. Этот процесс и то, что «когда нужно» метод обнаружения условий - это то, что мне было бы интересно понять.
Update 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
Спасибо, это прекрасно! –