OberonCore
 

Пишем свой первый модуль

Ермаков И. Е.

11.12.2005 г.

Статья поможет новичку сделать первые шаги в среде BlackBox. Фрагмент учебных материалов, используемых в лицее №1 г. Орла.

Построение модуля

Для решения различных задач в BlackBox программист должен создавать собственные модули. Те, кто работал с традиционными средствами разработки, например, Borland Pascal, привыкли получать в результате отдельное приложение - файл с расширением .exe. В BlackBox практикуется иной подход: запускаемым приложением является сама среда, а в ней уже работают различные модули, как стандартные, так и созданные программистом. В конечном счете пользователю поставляется тот же самый BlackBox, в котором работал программист. Переделываются меню, некоторые подсистемы удаляются (например, сам компилятор и инструменты разработки - подсистема Dev). Такой непривычный подход дает очень большую гибкость, особенно при создании больших программных комплексов, которые непрерывно развиваются. Заметим, что при желании все модули и даже ресурсы можно скомпоновать в один .exe-файл, можно даже собрать программу совсем без оконного интерфейса.

Итак, приступим к созданию своего первого программного модуля. Как мы уже знаем, модули BlackBox группируются в подсистемы. Поэтому создадим для наших модулей новую подсистему Stud. Откройте директорию BlackBox и создайте поддиректорию Stud, а в ней, в свою очередь - Mod (для исходных текстов модулей) и Rsrc (для ресурсов). Разделы Code и Sym BlackBox создаст автоматически, когда мы будем компилировать исходные тексты.

  MODULE StudHellow;
      IMPORT StdLog;
 
      PROCEDURE Сказать*;
      BEGIN
          StdLog.String("Здрасте!")
      END Сказать;
 
  END StudHellow.

Обратите внимание на то, что следует соблюдать регистр. Все ключевые слова Компонентного Паскаля пишутся заглавными буквами. Это облегчает чтение исходников. Однако подсветка ключевых слов (цветом или жирностью), которая принята в других средах, в BlackBox не используется. Вместо этого программист волен выделять шрифтом, начертанием, цветом все, что посчитает нужным. Принято выделять жирным начертанием те части модуля, которые экспортированы, то есть, доступны извне.

Сохраним набранный документ под именем Hellow в директории Stud/Mod. Обратим внимание на именование модулей. Полное имя нашего модуля - StudHellow. Первая его часть - до второй заглавной буквы - трактуется средой как имя подсистемы (а значит - директории, в которой ищутся исходные и двоичные коды модуля), а вторая - как имя модуля в подсистеме (то есть, имя файла, в котором хранится код). Имя подсистемы не должно содержать несколько заглавных букв. Так, правильными именами для подсистемы являются: Subs, Graph, My_subsystem, а неправильным: MySubsystem. В то же время включение нескольких заглавных букв в имя модуля не только не запрещено, но общепринято. Вообще в BlackBox для разделения слов в идентификаторах обычно не используется знак подчеркивания _, а вместо этого каждое слово пишется с заглавной буквы: StudSecondModule. Теперь настало время откомпилировать, загрузить и заставить работать наш первый модуль. Для этого запустим команду меню Dev→Compile, или, что гораздо удобней, нажмем сочетание клавиш Ctrl-K. Если текст модуля был набран правильно, то в окне протокола появится запись compiling «StudHellow» 28 0. Это значит, что модуль был успешно откомпилирован в бинарный исполняемый код в файле Stud/Code/Hellow.ocf и был создан символьный файл Stud/Sym/Hellow.osf с информацией о том, какие процедуры и другие компоненты содержит в себе модуль StudHellow. «Полезную» работу в нашем модуле выполняет процедура Сказать. Она должна вывести в окно протокола строку «Здрасте!». Встает вопрос: как выполнить (обычно говорят - вызвать) процедуру Сказать. Это может быть сделано различными способами. Например, ее может вызвать какой-либо другой модуль, который импортирует наш. Но нам нужен другой вариант - вызов вручную. Самый простой способ - написать команду в любом текстовом документе (например, в протоколе):

StudHellow.Сказать

Заметим, что между именем модуля и именем процедуры ставится разделитель - точка. Такое имя, начинающееся с имени модуля, называется полным, или составным именем.

Чтобы заставить среду выполнить нашу команду, выделим ее и выберем пункт меню Dev→Execute. Есть и другой, более удобный способ - вставить в текст перед командой так называемый командир. Для этого установите курсор в нужное место и выберите Tools→Insert Commander или нажмите Ctrl-Q.

Сразу после командира напишите: «StudHellow.Сказать»
Если все сделано правильно, то в протоколе появится запись «Здрасте!».

Изучаем наш модуль

Теперь разберемся в исходнике нашего модуля. Ниже приведен текст, в который вставлены комментарии. Комментарием называется часть текста, которая игнорируется компилятором. Она берется в скобки (* и *). Между скобками может быть написано все, что угодно. Комментарии принято выделять курсивом.

  MODULE StudHellow;
 
  (* С этой строчки начинается любой модуль BlackBox.
  Перед именем модуля Hellow стоит имя подсистемы Stud.
  Инструкции в КП разделяются точкой с запятой *)
 
      IMPORT StdLog;
      (* В директиве импорта мы говорим компилятору, что наш модуль пользуется
       процедурами модуля StdLog. Этот модуль предназначен для вывода в протокол*)
 
      PROCEDURE Сказать*;
      (* Определим процедуру Сказать. Звездочка * после имени процедуры означает,
      что она экспортирована - то есть, доступна извне модуля. Имена 
      экспортированных элементов принято выделять жирным шрифтом *)
      BEGIN  (* Со слова BEGIN начинается секция кода процедуры *)
          StdLog.String("Здрасте!")
          (* Вызываем процедуру String модуля StdLog.
          В скобках записываем параметр - строку в кавычках.
          Перед END точку с запятой можно - и принято - не ставить. *)
      END Сказать;
         (* Процедура завершается фразой END имя_процедуры *)
         (* Модуль завершается фразой END имя_модуля. В конце модуля ставится точка *)
  END StudHellow.

Как строится документ с исходным текстом? С самого начала он должен содержать правильное определение модуля, которое начинается с фразы MODULE имя_модуля и заканчивается фразой END имя_модуля .. После точки в конце модуля в документе может находиться любой текст (например, командиры для вызова команд модуля) - он игнорируется компилятором.

Внесение изменений в модуль. Загрузка и выгрузка модулей

Теперь попробуем внести в наш модуль некоторые изменения. Например, выводить в протокол не одну, а несколько строк. Для этого в секцию кода процедуры Сказать допишем следующие вызовы:

  PROCEDURE Сказать*;
  BEGIN
      StdLog.String("Здрасте!");
      StdLog.Ln; (* Процедура Ln выводит в протокол символ новой строки *)
      StdLog.String("Меня зовут Черный Ящик!");
      StdLog.Ln
  END Сказать;

Откомпилировав модуль и вызвав процедуру Сказать, мы увидим, что почему-то наши изменения не работают - в протокол по-прежнему выводится одно слово «Здрасте!».

Дело в том, что при первом обращении к процедурам модуля его код загружается в память и остается там до закрытия BlackBox. То есть, в памяти все еще находится старая версия модуля, немотря на то, что на диск записан уже новый кодовый файл .ocf. Поэтому после перекомпиляции модуля старую версию следует выгрузить из памяти. Для этого следует выделить в любом тексте имя модуля и выбрать Dev>Unload. Модуль будет выгружен из памяти, и при следующем вызове процедуры в память будет загружена уже новая его версия.

В BlackBox есть средство, которое позволяет просмотреть список загруженных в память модулей. Для этого выберите Info'>Loaded Modules. Будет открыт документ со списком загруженных модулей, информацией о количестве использованной ими памяти и т.п. Можно выделить часть этого списка и выбрать Dev'>Unload Module List. Будут выгружены все выделенные модули (если они не используются другими модулями).

При многократном внесении изменений удобно компилировать код командой Dev'>Compile And Unload, которая сразу же выгружает старую версию модуля. Ошибки компиляции

Компиляция модуля проходит успешно, только если в исходном тексте нет ошибок. Давайте попробуем их специально внести. Например, не поставим точку с запятой между операторами:

  PROCEDURE Сказать*;
  BEGIN
      StdLog.String("Здрасте!");
      StdLog.Ln; (* Процедура Ln выводит в протокол символ новой строки *)
      StdLog.String("Меня зовут Черный Ящик!")	(*!!!*)
      StdLog.Ln
  END Сказать;

Попробуем откомпилировать модуль. В протокол будет выведено сообщение 1 error detected, а в документ на место пропущенного разделителя - серый перечеркнутый значок, так называемый маркер ошибки. Щелкнем по этому маркеру - в строке состояния (внизу окна среды) появится комментарий к ошибке: ; missing, что по-русски означает «отсутствует точка с запятой». Исправив ошибку, можно снова компилировать модуль - все пройдет нормально, а маркеры ошибок исчезнут из документа. Просмотр информации о модулях

В среде BlackBox могут находиться тысячи модулей - как стандартные, так созданные программистом. Держать в голове имена и списки параметров каждой процедуры, которая в них находится, просто невозможно. В этом программисту помогает информация о содержимом модуля, которая автоматически считывается средой, и файлы документации, в которые разработчики помещают описания своих модулей.

Давайте просмотрим содержимое модуля StdLog. Для этого выделим в тексте его имя и нажмем сочетание Ctrl-D (от слова Definition). Откроется окно со списком экпортированных элементов модуля. Набор экспортированных элементов называют интерфейсом модуля. Тот же эффект, что и Ctrl-D, дает Info→Client Interface, или нажатие правой кнопки мыши и выбор в открывшемся меню Interface. Можно выделить не имя модуля, а имя процедуры: StdLog.String и нажать Ctrl-D - будет показано описание одной этой процедуры. Документацию стандартных модулей можно просмотреть через меню Help, однако есть и более быстрый способ: выделить имя модуля и выбрать команду Info→(или контекстное меню)Documentation. Среда ищет документ с именем, таким же, как имя модуля (StdLog.odc) в директории Std / Docu. Если выделить имя конкретной процедуры, то среда попытается сразу открыть то место документа, в котором она описана. Попробуйте создать документ с описанием модуля StudHellow. Сохраните его под именем Stud / Docu / Hellow.odc - и теперь он будет точно так же открываться из среды, как и документация к стандартным модулям. И, наконец, таким же способом можно открывать исходные тексты модулей - выделяя имя модуля и выбирая Source.

 
Программирование
Главная
Оберон и оберон-технологии
Общие статьи
Библиотека
BlackBox
Среда
Документация
Компоненты
Статьи
Полигон
Образование
Статьи
Учебные материалы
Сообщество
Информатика-21
ООО «Метасистемы»
Европейский центр программирования
Oberon Community Platform
Королевство Делфи
© 2007, 2008, 2009 Проект "OberonCore".