Определяемые пользоватем классы
Файл в таком формате определяет пользовательский класс:
@CLASS
имя_класса
# необязательно
@USE
файл_с_родительским классом
# необязательно
@OPTIONS
locals
partial
dynamic или static [3.4.1]
# необязательно
# нельзя наследоваться от системных классов
@BASE
имя_родительского_класса
# так рекомендуется называть метод-конструктор класса
@create[параметры]
# далее следуют определения методов класса
@method1[параметры]
…
Модуль можно подключить (см. «Подключение модулей») к произвольному файлу - там появится возможность использования определенного здесь класса.
Если происходит обращение к неизвестному классу, вызывается метод autouse класса MAIN, и имя класса передается единственным параметром этому методу. [3.4.0]
Если не указать @CLASS, файл определит ряд дополнительных операторов.
Если определен метод…
@auto[]
код
…он будет выполнен автоматически при загрузке класса как статический метод (так называемый статический конструктор). Используется для инициализации статических полей (переменных) класса.
Примечание: результат работы метода игнорируется - никуда не попадает.
У метода auto может быть объявлен параметр:
@auto[filespec]
В этом параметре Parser передаст полное имя файла, содержащего метод.
В Parser создаваемые классы наследуют методы классов, от которых были унаследованы. Унаследованные методы можно переопределить.
Примечание: метод auto не наследуется, благодаря чему не происходит его множественного выполнения, сначала при инициализации родительского класса, а затем - текущего. [3.4.1]
В том случае, когда в качестве родительского класса выступает другой пользовательский класс, необходимо подключить модуль, в котором он находится, а также объявить класс базовым (@BASE).
Для того, чтобы пользоваться методами и полями родительских классов, необходимо использовать следующие конструкции:
^класс:метод[параметры] - вызов метода родительского класса (примечание: хотя такой синтаксис вызова метода и похож на синтаксис вызова статического метода, фактически, в случае динамического метода, происходит динамический вызов метода родительского класса), для обращения к своему ближайшему родительскому классу (базовому классу) можно использовать конструкции ^BASE::конструктор[параметры] и ^BASE:метод[параметры].
С помощью @OPTIONS можно определить дополнительное поведение класса.
Примечание: пробельные символы в конце метокоманд @USE, @CLASS, @BASE, @OPTIONS игнорируются. [3.4.1]
Так, указанная опция locals автоматически объявит локальными все переменные во всех методах определяемого класса. Если она указана, то для обращения к полям объекта или класса необходимо пользоваться системной переменной self.
С помощью опции partial можно разрешить последующую подгрузку методов в класс. Если впоследствии будет сделан use файла, в котором указано такое же имя класса и эта же опция, то вместо создания нового класса с таким же именем, описанные в подключаемом файле методы будут добавлены к ранее загруженному классу. Опция может быть удобна для условного добавления в класс громоздких и редкоиспользуемых методов. После создания класса с использованием данной опции возможно лишь добавление методов классу, но не изменение его родительского класса.
С помощью опций static и dynamic можно задать возможный тип вызова определяемых в файле методов класса. По умолчанию описываемые в файле методы могут вызываться как динамически так и статически, что может быть не всегда безопасно, и эти опции помогут запретить небезопасные вызовы.
Пример:
@CLASS
my
@OPTIONS
dynamic
# вызов $object[^my::create[]] будет допустим, а вызов $var[^my:create[]] будет вызывать исключение
@create[]
Код
# вызов ^object.method1[] будет допустим, а вызов ^my:method1[] будет вызывать исключение
@method1[]
Код
# вызов ^my:method2[] будет допустим, а вызов ^object.method2[] будет вызывать исключение
@static:method2[]
Код
Работа с переменными в статических методах
Поиск значения переменной происходит в:
· | в списке локальных переменных;
|
· | в текущем классе или его родителях.
|
Запись значения переменной производится в уже имеющуюся переменную (см. область поиска выше), если таковая имеется. В противном случае создается новая переменная (поле) в текущем классе.
Работа с переменными в динамических методах
Поиск значения переменной происходит в:
· | в списке локальных переменных;
|
· | в текущем объекте и его классе;
|
· | в родительских объектах и их классах.
|
Запись значения переменной производится в уже имеющуюся переменную (см. область поиска выше), если таковая имеется. В противном случае создается новая переменная (поле) в текущем объекте.
Примечание: старайтесь всячески избегать использования полей класса не из методов класса, кроме простейших случаев! По-возможности, общайтесь с объектом только через его методы.
Системное поле класса: CLASS
$имя_класса:CLASS - хранит ссылку на класс объекта.
Это удобно при задании контекста компиляции кода (см. «process. Компиляция и исполнение строки».
По этой ссылке также доступны статические поля класса, пример:
@main[]
^method[$cookie:CLASS]
@method[storage]
$storage.field
Этот код напечатает значение $cookie:field.
Системное поле класса: CLASS_NAME $объект.CLASS_NAME - хранит имя класса объекта.
Пример
$var[123]
$var.CLASS_NAME
Выведет 'string'.