Библиотека сайта rus-linux.net
Среда времени выполнения динамических языков и языки Iron
Глава 8 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: The Dynamic Language Runtime and the Iron Languages
Автор: Jeff Hardy
Перевод: Н.Ромоданов
8.9. Хост-среда
Кроме обеспечения общих особенностей реализации языков, в среде DLR также предоставлен елиный используемый хост-интерфейс (hosting interface). Хост-интерфейс используется хост-языком (обычно статическим языком, например, языком C#) для выполнения кода, написанного на другом языке, например, на языке Python или Ruby. Это обычный метод, который позволяет конечным пользователям расширять приложение, а среда DLR двигается на шаг вперед, делая тривиальным использование любого скриптового языка, реализация которого есть в среде DLR. В хост-инстрефейсе присутсвуют следующие четыре ключевые компонента: среда времени выполнения runtime, движки engines, средства работы с исходным кодом sources и механизмы scopes, реализующие среду выполнения кода.
Среда времени выполнения ScriptRuntime
, как правило, используется совместно всеми динамическими языками, имеющимися в приложении. Среда времени выполнения обрабатывает все текущие ссылки, которые присутствуют на загруженный языках, предоставляет методы быстрого выполнения файлов, а также предоставляет методы создания новых движков. Для простых скриптовых задач, среда времени выполнения является лишь интерфейсом, которым необходимо пользоваться, но в DLR также предлагаются классы, обеспечивающие лучший контроль над тем, как выполняются скрипты.
Как правило, для каждого скриптового языка используется только один движок ScriptEngine
. Поскольку используется протокол мета-объектов среды DLR, то это значит, что программа может загружать скрипты, написанные на различных языках, а объекты, созданные на каждом отдельном языке, могут легко взаимодействовать между собой. Движок представляет собой обвертку вокруг контекста LanguageContext
, специфического для каждого конкретного языка (например, PythonContext
или RubyContext
), и используется для выполнения кода, загружаемого из файла или строк, а также для выполнения операций над динамическими объектами для языков, в которых изначально среда DLR не поддерживается (например, язык C# до версии .NET 4). Движки являются поточно-ориентированными и поскольку каждый поток работает в своей собственной области видимости, параллельно могут выполнять несколько скриптов. Также предоставляются методы, применяемые при написании исходных кодов скриптов и обеспечивающие более детальный контроль над выполнением скрипта.
Фрагменты кода, который должен выполняться, содержатся внутри класса ScriptSource
; этот компонент привязывается объект SourceUnit
, в котором хранится фактический код, к движку ScriptEngine
, для которого создан исходный код. Этот класс позволяет компилировать этот код (в результате создается объект CompiledCode
, который можно кэшировать) и непосредственно его выполнять. Если фрагмент кода будет выполняться неоднократно, то его лучше сначала скомпилировать, а затем выполнять скомпилированный код; для скриптов, которые выполняются однократно, код лучше просто непосредственно выполнить.
Когда, в конце концов, потребуется выполнить код, то с помощью механизма ScriptScope
нужно будет создать среду, в которой он будет выполняться. Эта среда используется для хранения всех переменных, используемых в скрипте, и в ней может выполнять, если это необходимо, предварительную загрузку переменных из хост-среды. Это позволяет хост-среде передавать пользовательские объекты в скрипт, когда тот начинает работать; например, когда скрипт работает, то можно с помощью редактора изображений предоставить метод для доступа к пикселям изображения. После того, как скрипт закончит работать, из среды работы скрипта можно будет прочитать переменные, которые он создал. Другой основной особенностью среды выполнения является то, что она изолирует работу скрипта, поэтому одновременно можно загружать и выполнять несколько скриптов, которые не будут мешать друг другу.
Важно отметить, что все эти классы предоставляются средой DLR, а не языком; из реализации языка в движке используется только класс контекста языка LanguageContext
. В контексте языка предоставляются все функциональные возможности: загрузка кода, создание среды выполнения, компиляция, выполнение кода и выполнение операций над динамическими объектами — то, что необходимо хост-среде, а в среде DLR предоставлются классы, обеспечивающий более удобный интерфейс доступа к этим функциональным возможностям. Благодаря этому один и тот же код хост-среды можно использовать для любого языка, разрабатываемого в среде DLR.
Чтобы реализовать динамический язык, написанный на языке C (например, оригинальные языки Python и Ruby), в динамическом языке необходимо написать специальный код-обвертку, причем это требуется повторять для каждого поддерживаемого скриптового языка. Хотя есть программы, например, SWIG, которые упрощают эту работу, добавить в программу скриптовый интерфейса языка Python или Ruby и предоставить внешним скриптам возможность работать с объектной моделью все еще продолжает оставаться нетривиальной задачей. Однако в среде .NET добавление возможности использования скриптов выполняется достаточно просто с помощью помощи настройки среды выполнения, загрузки в среду выполнения частей программы и применение метода ScriptScope.SetVariable()
для того, чтобы объекты программы стали доступными для скриптов. Можно в течение нескольких минут добавить в приложение среды .NET поддержку выполнения скриптов, что является огромным преимуществом среды DLR.
8.10. Общая структура
Поскольку среда DLR эволюционировала из отдельной библиотеки в часть среды CLR, есть компоненты, которые, которые находятся в среде CLR (точки вызовов, деревья выражений, средства привязки, генерация кода и динамические метаобъекты), и компоненты, которые являются частью проекта языков IronLanguages, имеющего открытый исходный код (хостинг, интерпретатор и несколько других небольших компонентов, которые здесь не рассматриваются). Компоненты, находящиеся в среде CLR, также включены в состав проекта IronLanguages в виде компонента Microsoft.Scripting.Core
. Компоненты среды DLR разделены на две составляющие - Microsoft.Scripting
и Microsoft.Dynamic
— к первой относятся интерфейсы API хостинга, а во второй находится код взаимодействия с объектами COM, интерпретатор и некоторые другие общие компоненты динамических языков.
Сами языки также разделены на две составляющие: в IronPython.dll
и IronRuby.dll
реализованы сами языки (синтаксические анализаторы, средства привязки и т.д.), а в IronPython.Modules.dll
и IronRuby.Libraries.dll
реализованы те части стандартной библиотеки, которые в классических реализациях языков Python и Ruby написаны на языке C.
Продолжение статьи: Усвоенные уроки