1.2.3

## Начальная загрузка

Начальная загрузка — это процесс запуска функций системы, подготавливающий возможность исполнения кода на Ruby. Она проходит семь стадий:

1. VM: виртуальная машина способна загружать и выполнять байткод, посылать сообщения (то есть, находить и вызывать методы); все примитивные функции уже доступны, но еще не видны как методы Ruby.

   Класс `Class` на этой ранней стадии должен быть явно задан путем объявления самого себя своим классом, а своим суперклассом — `Module`. В дополнение к `Class` и `Module` здесь же создаются еще несколько базовых классов, включая `Object`, `Tuple`, `LookupTable` и `MethodTable`.

   Теперь, когда уже можно определять классы, получают приказ начать самоинициализацию еще около 35 встроенных классов; создаются символы для методов высшего уровня `:object_id`, `:call`, `protected` и т.п.; определяются базовые исключения (exceptions) и регистрируются примитивы.

   В этот момент уже определено поведение, достаточное для того, чтобы начать загружать остальное runtime-ядро, целиком написанное на Ruby. Это, в свою очередь, также делается в несколько проходов по мере «роста» языка.

2. Альфа: начало загрузки кода на Ruby. Уже есть возможность открывать классы и модули и определять методы. В `kernel/alpha.rb` реализованы минимальные средства для поддержки следующих методов:

       attr_reader :sym
       attr_writer :sym
       attr_accessor :sym
       private :sym
       protected :sym
       module_function :sym
       include mod

   Помимо этого код имеет возможность инициировать исключения и прекращать выполнение процесса. Эта стадия закладывает основание для следующих двух.

3. Бутстрап: продолжается добавление минимального функционала для поддержки загружающихся «платформы» и «основы» (“platform” и “common”, см. ниже). Функции-примитивы добавляются в большинство классов ядра.

4. Платформа: запускается FFI (интерфейс внешних функций) и создаются интерфейсные методы платформо-специфических функций. Как только все это настроено, к системе подключаются платформо-специфические детали вроде указателей, файловых операций, арифметики и вызовов POSIX.

5. Основа: создается подавляющее большинство классов Основной (`core`) библиотеки. Основные классы Ruby построены настолько независимо от конкретной реализации, насколько это возможно. На этом же этапе добавляется бóльшая часть функциональных возможностей Rubinius-специфических классов.

6. Дельта: добавляются финальные версии методов из ряда `#attr_reader` и т.п. Кроме этого, подключаются зависимые от реализации версии методов Основы.

7. Загрузчик: выполняется скомпилированная версия `kernel/loader.rb`.

   Конечная стадия загрузки настраивает жизненный цикл Ruby-процесса. Она начинается с присоединения виртуальной машины к системе, затем настраиваются пути загрузки, читаются скрипты индивидуальной настройки из домашней директории. На этом этапе улавливаются сигналы и обрабатываются аргументы командной строки.

   После всего либо запускается переданный в командной строке скрипт, либо стартует интерактивная оболочка Ruby. Когда и они заканчивают работу, отрабатываются все зарегистрированные блоки `at_exit`, финализируются все объекты и процесс прекращается.

## Порядок загрузки

Ряд описанных стадий загрузки реализован в файлах, находящихся в соответствующих директориях ядра: `bootstrap`, `platform`, `common`, и `delta`. Порядок загрузки этих директорий определен в `runtime/index`.

Код уровня скрипта, тела класса или модуля выполняется после загрузки rbc-файла. К примеру, при загрузке фрагмента

    class SomeClass
      attr_accessor :value
    end

выполняется вызов `#attr_accessor`. Для этого требуется, чтобы до файла, содержащего некий код, было загружено все, что вызывается из содержащихся в нем описаний скриптов, классов и модулей. `kernel/alpha.rb` содержит бóльшую часть определений, необходимых на уровне скрипта или модуля. Вместе с тем, между некоторыми файлами платформы, основы, дельты и компилятора существуют и иные зависимости, влияющие на порядок загрузки.

Эти зависимости прописаны в файлах `load_order.txt`, находящихся в каждой из директорий `kernel/**`. Если Вы модифицируете код, добавляющий порядковую зависимость, Вам следует отредактировать соответствующий `load_order.txt`, поместив файл, который зависит, после того, от которого он зависит. Если Вы добавляете новый файл в одну из директорий ядра, Вы должны добавить его имя в `load_order.txt` его директории. При сборке эти файлы копируются в соответствующие директории `runtime/**`. Во время каждой из вышеописанных стадий запуска виртуальная машина загружает файлы в порядке их перечисления в `load_order.txt`.