Атрибуты переменных и объектов
AUTO (локальная переменная без начального значения)
AUTO
Атрибут
AUTO разрешает распределение переменной, объявленной внутри процедуры, неинициализированной памяти в стеке. При распределении памяти во время выполнения программы, числовой переменной без атрибута AUTO присваивается начальное значение 0, а строковая переменная инициализируется пробелами.Атрибут AUTO используется когда не нужно быть уверенным в нулевом или пробельном начальном значении переменной, поскольку вы намереваетесь присвоить ей некое отличное от нуля или пробелов значение. Этот атрибут экономит небольшое количество памяти во время выполнения, исключая фрагмент программного кода, необходимый для автоматической инициализации переменной
.Когда объявлен тип данных
ANY вне структуры, атрибут AUTO игнорируется. Когда структура содержит ANY с атрибутом AUTO, необходимо сперва целиком очистить структуру перед тем как получать доступ к переменным типа ANY.Пример
:SomeProc PROCEDURE
SaveCustID LONG,AUTO !
Неинициализированная локальная переменнаяСмотри также:
Объявление данных и распределение памятиmemo-поле содержит двоичные данные)
BINARY
Атрибут
BINARY (PROP:BINARY) в объявлении MEMO- или BLOB-поля указывает, что поле будет содержать данные, которые являются не только символами ASCII. Обычно этот атрибут используется для того, чтобы хранить небольшие графические изображения, предназначенные для отображения в полях типа IMAGE структуры SCREEN (или WINDOW, прим. пер). OEM конвертация неприменима в MEMO- или BLOB-полях с атрибутом BINARY. Некоторые файловые драйверы (Clarion, Btrieve, xBase) указывают, что данные в двоичном виде MEMO- и BLOB-полей – заполняются нолями, в то время как недвоичные данные – пробелами.Пример
:Names FILE,DRIVER('Clarion'),PRE(Nam)
NbrKey KEY(Nam:Number)
Picture MEMO(48000),BINARY
!двоичное MEMO - 48,000 bytesRec RECORD
Number SHORT
END
END
Смотри
также: MEMO, BLOB, IMAGE, OEMпеременная, используемая в динамических выражениях)
BINDABLE
Атрибут
BINDABLE объявляет структуры GROUP, QUEUE, FILE и VIEW, составляющие переменные которых, можно использовать в динамических выражениях во время выполнения программы. Значение атрибута NAME каждой из переменных является логическим именем, используемым в динамических выражениях. Если атрибут NAME отсутствует, то используется имя переменной (включая префикс). Для имен всех переменных структуры в исполняемом модуле выделяется память. Таким образом, программа становится больше и использует больше памяти, чем обычно. Поэтому атрибут BINDABLE следует использовать, только если большая часть переменных структуры используется в динамических выражениях.Форма
BIND(группа) оператора BIND должна применяться в исполняемом коде перед использованием отдельных полей структуры QUEUE.Пример:
Names QUEUE,BINDABLE
! Объявить структуру Record,! которую можно использовать в динамических выражениях
Name STRING(20)
FileName STRING(8),NAME('FName') !
Динамическое имя: FNameDot STRING
(1) ! Динамическое имя: DotExtension STRING(3),NAME('EXT') !
Динамическое имя: EXTEND
CODE
BIND(Names)
Names FILE,DRIVER('Clarion'),BINDABLE
! Объявить структуру Record,
! которую можно использовать в динамических выражениях
Record RECORD
Name STRING(20)
FileName STRING(8),NAME('FName') !
Динамическое имя: FNameDot STRING
(1) ! Динамическое имя: DotExtension STRING(3),NAME('EXT') !
Динамическое имя: EXTEND
END
CODE
OPEN(Names)
BIND(Names)
FileNames GROUP,BINDABLE !
Объявить структуру Group,! которую можно использовать в динамических выражениях
FileName STRING(8),NAME('FILE') !
Динамическое имя: FILEDot STRING
('.') ! Динамическое имя: DotExtension STRING(3),NAME('EXT') !
Динамическое имя: EXTEND
Смотри
также: BIND, UNBIND, EVALUATE
CREATE (разрешить создание файла)
CREATE
Атрибут
CREATE (PROP:CREATE) в описании файла разрешает создание оператором CREATE дискового файла в программе, в которой этот файл объявляется. Тем самым привносятся некоторые накладные расходы, поскольку вся необходимая для этого информация должна содержаться в исполняемом модуле.Пример
:Names FILE,DRIVER('Clarion'),CREATE !
Объявить файл, разрешить создание егоRec RECORD
Name STRING(20)
END
END
DIM (установить размерность массива)
DIM(
размерность,...,размерность)DIM
Объявить переменную-массив.размерность Числовая константа, которая указывает число элементов в этом измерении массива.
Атрибут DIМ объявляет переменную как массив. Переменная повторяется столько раз, сколько указывает параметр размерность. Многомерные массивы можно рассматривать как вложенные. Каждое измерение массива имеет свой индекс. Таким образом ссылка на элемент трехмерного массива требует указания трех индексов. На число измерений ограничения нет и общий размер массива неограничен. Нулевое или отрицательное значение элемента массива недопустимо
.Индексы уточняют, к какому элементу массива происходит обращение. Список индексов содержит индекс для каждого измерения массива. Каждый индекс отделяется запятой, а весь список заключается в квадратные скобки ([ ]). Индекс может быть представлен числовой константой, выражением или функцией. К целому массиву можно обратиться по имени без указания списка индексов.
Структура GROUP представляет собой особый случай. Каждый уровень вложенности добавляет индекс группе и переменным внутри группы. Данные, объявленные в GROUP имеют ссылки, использующие стандартный синтаксис Уточнения имени переменной с каждым индексом, указанным на том уровне GROUP, на котором он измеряется.
Пример:
Scr GROUP !Символы на экране
Row GROUP,DIM
(25) !двадцать пять строкPos GROUP,DIM
(80) !две тысячи позицийAttr BYTE !Байт атрибутов
Char BYTE !Байт символа
END
!Завершение структур GRОUРEND
END
! В приведенной выше группе:
! Scr группа из 4000 байт
! Scr.Row
группа из 4000 байт! Scr.Row
[1] из 160 байт! Scr.Row[1].Pos
из 160! Scr.Row[1].Pos
[1] из 2 байт! Scr.Row[1].Pos[1].Attr 1
байт! Scr.Row[1].Pos[1].Char 1
байтMonth STRING(10),DIM(12) !
Двенадцать месяцевCODE
CLEAR(Month) !Очистить весь массив
Month[1] = 'January
' !Присвоить значения элементам массиваMonth[2] = 'February'
Month[3] = 'March'
Смотри также:
MAXIMUM, Списки передаваемых параметров(передача массивов)
DLL (переменная определена в библиотеке .DLL)
DLL(
[ флаг ] )DLL
флаг Числовая константа, метка соответствия, или определение системы поддержки проекта, которое задает активен ли данный атрибут. Если флаг установлен в 0, то этот атрибут неактивен, как если бы его вообще не было. Если флаг имеет отличное от нуля значение, то атрибут активен.
Атрибут
DLL указывает, что объявление (это могут быть структуры FILE, QUEUE, GROUP или CLASS), к которому он относится размещено в библиотеке .DLL. Объявление с атрибутом DLL должно иметь еще и атрибут EXTERNAL. Для 32-битовых приложений атрибут DLL обязателен, так как такие библиотеки являются настраиваемыми (перемещаемыми) в 32-битовом адресном пространстве, которое требует от компилятора еще одного дополнительного разыменовывания (преобразования адреса) при обращении к переменной. Атрибут DLL допустим только для переменных, объявленных вне структур FILE, QUEUE, CLASS или GRОUР.Объявления переменных во всех библиотеках (или .EXE - модулях), которые ссылаются на общие переменные, должны быть в точности одинаковыми (с соответствующим добавлением атрибута EXTERNAL и DLL). Если объявления отличаются, то может произойти разрушение данных. Ответственность за соблюдение идентичности объявлений лежит на программисте, поскольку ни компилятор ни компоновщик не могут определить несоответствия объявлений в различных программах и библиотеках.
При использовании атрибутов EXTERNAL и DLL для объявления переменной совместно используемой .DLL и .EXE только в одной из них переменная, файл, класс или очередь должны объявляться без этих атрибутов. Во всех других библиотеках и программах следует объявлять переменную, файл, класс или очередь
с атрибутами DLL и EXTERNAL. Это обеспечит уверенность в том, что для переменной, файла, класса или очереди распределена только одна область памяти и во всех библиотеках и программах при обращении к ней будут ссылки на одну и ту же область памяти, занимаемую переменной, файлом или очередью.Можно посоветовать при разработке больших систем, использующих много библиотек DLL и/или EXE модулей, которые совместно используют одни и те же переменные, собирать реальные описания разделяемых глобальных переменных и файлов, совместно использующих все (или большинство) библиотек или исполняемых модулей, в одну библиотеку DLL. Таким образом создается одна центральная библиотека, в которой происходит отслеживание всех действительных объявлений переменных. Эта центральная библиотека связывается со всеми программами, которые используют общие переменные. Во всех других библиотеках и(или) программах в этой системе общие переменные должны объявляться с атрибутами EXTERNAL и DLL.
Флаг, используемый
IDE системы поддержки проекта и генератором аппликаций:_ABCDllMode_
Используется шаблонами ABC для всех объявлений классов, чтобы указать, что класс объявлен во внешней библиотеке .DLL. В проекте – для указания переключения в режим DLL.Пример
:TotalCount LONG,EXTERNAL,DLL(dll_mode) !
Переменная, объявленная во внешней!библиотеке
Cust FILE,PRE(Cus),EXTERNAL(''),DLL
(1) !Файл, объявленный в модуле PROGRAM из .DLLCustKey KEY(Cus:Name)
Record RECORD
Name STRING(20)
END
END
DLLQueue QUEUE,PRE(Que),EXTERNAL,DLL(1) !
Очередь, объявленная во внешней!библиотеке
.DLLTotalCount LONG
END
EditEntryClass CLASS(EditClass),TYPE,MODULE('ABEIP.CLW'),LINK('ABEIP.CLW',|
_ABCLinkMode_),DLL(_ABCDllMode_)
CreateControl PROCEDURE,VIRTUAL,PROTECTED
END
Смотри также:
EXTERNAL
DRIVER (указать тип файловой системы)
DRIVER(
тип файла [,строка])DRIVER
Указывает какую файловую систему этот файл использует.тип файла Строковая константа, содержащая имя файлового менеджера (драйвера) (
Btrieve, Clarion и т.д.)строка драйвера Строковая константа или переменная, содержащая любые дополнительные команды файловому драйверу. Все допустимые для этого параметра значения перечислены в документации каждого из файловых драйверов.
Атрибут
DRIVER (PROP:DRIVER) указывает какой файловый драйвер используется для доступа к этому файлу данных. Это обязательный атрибут в объявлении любого файла.Для осуществления физического доступа к файлу Clarion-программа использует файловый драйвер. Файловый драйвер действует как транслятор между Clarion-программой и файловой системой, исключая несвойственные для данной файловой системы команды. Файловые драйверы позволяют обращаться к файлам различных файловых систем, оставаясь в рамках синтаксиса языка Clarion.
Конкретный способ реализации каждой команды доступа к файлу в Clarion зависит от файлового драйвера. Из-за ограничений конкретной файловой системы некоторые команды могут быть не реализованы в драйвере. Каждый файловый драйвер описывается в Руководстве пользователя. Там перечисляются все неподдерживаемые команды доступа к файлу, атрибуты объявления файла, типы данных и/или особенности файловой системы.
Если файл объявлен без атрибута
THREAD, строка драйвера (PROP:DriverString), используемая с атрибутом DRIVER, также должна быть объявлена без атрибута THREAD.Пример
:Names FILE,DRIVER('Clarion') !
Начало объявления файлаRecord RECORD
Name STRING(20)
END
END
!Использование запятых для разделения нескольких строк драйвера:
A FILE,PRE(ASC),DRIVER('BASIC','/ALWAYSQUOTE=OFF,/COMMA=9,/ENDOFRECORD=1,13')
Record RECORD
Name STRING(20)
END
END
DUP (допускается повторение значений ключа)
DUP
Атрибут
DUP (PROP:DUP) в объявлении ключа допускает наличие в файле нескольких записей с одинаковым значением ключа. Если же атрибут DUP опущен, то попытка добавить запись (или изменить данные в существующей записи) со значением ключа, уже имеющимся в файле, приведет к выдаче сообщения об ошибке “Creates Duplicate Key”, а запись в файл не запишется. Во время последовательной обработки записей с использованием последовательности ключа, записи с одинаковым значением ключа обрабатываются в том порядке, в котором они соответствуют физическому расположению в файле ключей. Операторы SET и GET обращаются к первой записи из набора имеющих одинаковый ключ. В объявлении индексов атрибут DUP не нужен, поскольку индекс всегда допускает повторение значения элементов.Пример
:Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name),DUP !
Объявить ключ по полю имя, допустить совпадающие именаNbrKey KEY(Nam:Number) !
Объявить ключ по полю номер, повтор номеров недопустимRec RECORD
Name STRING(20)
Number SHORT
END
END
Смотри
также: KEY, GET, SET
ENCRYPT (шифрование файла данных)
ENCRYPT
Атрибут
ENCRIPT (PROP:ENCRYPT) используется с атрибутом OWNER для того, чтобы скрыть информацию в файле данных. Этот атрибут допустим только вместе с атрибутом OWNER. Даже с помощью утилиты просмотра в шестнадцатеричном формате крайне трудно расшифровать данные в зашифрованном файле.Пример
:Names FILE,DRIVER(‘Clarion’),OWNER(‘Clarion’),ENCRYPT
Record RECORD
Name STRING(20)
END
END
Смотри также
: OWNER, EXTERNAL
EXTERNAL (файл объявлен во внешнем модуле)
EXTERNAL(
member-модуль )EXTERNAL
Указывает, что структура FILE, QUEUE, GROUP или CLASS описывается во внешней библиотеке.member-модуль Строковая константа (допустима только в объявлении файла, группы или очереди). Содержит имя файла (без расширения) - member-модуля, содержащего описание файла, группы или очереди без атрибута EXTERNAL. Если структура FILE,
GROUP или QUEUE описывается в программном модуле или в “универсальном модуле” (т.е. оператор MEMBER для этого модуля не имеет параметра), то требуется, чтобы параметр атрибута EXTERNAL был пустой строкой или опущен.Атрибут
EXTERNAL указывает что переменная, файл, очередь, группа или класс к которому он относится, определены во внешней библиотеке. Таким образом, переменная, файл, очередь, группа или класс с атрибутом EXTERNAL объявляется и может использоваться в Clarion-программе, но память для буфера записи не выделяется. Память для буфера записи переменной, файла, очереди, группы или класса выделяется во внешней библиотеке. Этот атрибут позволяет Clarion-программе получить доступ к файлам, объявленным во внешней библиотеке как “public” - общие. Атрибут EXTERNAL недопустим в переменных, объявленных в структурах FILE, QUEUE, GROUP или CLASS.
При использовании атрибута EXTERNAL (member-модуль) для объявления файла, совместно используемого несколькими библиотеками (.LIB , .DLL и .EXE) только в одной из них этот файл должен объявляться без атрибута EXTERNAL. Во всех других библиотеках и программах следует объявлять этот файл с атрибутом EXTERNAL. Это обеспечит уверенность в том, что для него, всех библиотек и исполняемых программ распределен только один буфер записи и во всех библиотеках и программах при обращении к нему будут ссылки на одну и ту же область памяти.
Объявления файлов во всех библиотеках (или .EXE - модулях) должны быть абсолютно одинаковыми (с соответствущими добавленными атрибутами
EXTERNAL и DLL). Например, объявления файла во всех библиотеках (или .EXE-модулях), которые ссылаются на эти общие файлы, должны содержать в точности одинаковые ключи, мемо и поля, объявленные точно в таком же порядке. Если объявления отличаются, то может произойти разрушение данных. Реальные последствия несовместимости объявлений файла зависят от драйвера для данной файловой системы. Ответственность за соблюдение идентичности объявлений лежит на программисте, поскольку ни компилятор не компоновщик не могут определить несоответствия объявлений в различных программах и библиотеках.Не размещайте атрибуты
OWNER, ENCRYPT или NAME в файле, который имеет атрибут EXTERNAL. Эти атрибуты могут быть размещены только в файле, не имеющего атрибут EXTERNAL, потому что этот атрибут на самом деле переобъявит файл уже объявленный в другом месте. Следовательно, эти атрибуты необязательны.Можно посоветовать при разработке больших систем, использующих много библиотек DLL и/или EXE модулей, которые совместно используют одни и те же переменные, собирать реальные описания разделяемых глобальных переменных и файлов, совместно использующих все (или большинство) библиотек или исполняемых модулей, в одну библиотеку DLL. Таким образом, создается одна центральная DLL, в которой происходит отслеживание всех действительных объявлений переменных. Эта центральная библиотека связывается со всеми программами, которые используют общие переменные. Во всех других библиотеках и/или программах в этой системе общие переменные должны объявляться с атрибутами EXTERNAL.
Пример
:Пример:
PROGRAM
MAP
MODULE('LIB.LIB')
AddCount PROCEDURE !
Внешняя библиотечная процедураEND
END
TotalCount LONG,EXTERNAL !
Переменная объявлена во внешней библиотеке!
Структура файла определена в модуле PROGRAM библиотека которого включается в эту программуCust FILE,DRIVER('TopSpeed'),PRE(Cus),EXTERNAL('')
CustKey KEY(Cus:Name)
Record RECORD
Name STRING(20)
END
END
!
Структура файла определена в MEMBER модуле библиотека которого включается в эту программу
Contact FILE,DRIVER('TopSpeed'),PRE(Con),EXTERNAL('LIB01')
ContactKey KEY(Con:Name)
Record RECORD
Name STRING(20)
END
END
!**************************************
!
файл LIB.CLW содержит:PROGRAM
MAP
MODULE('LIB01')
AddCount PROCEDURE !
Библиотечная процедураEND
END
TotalCount LONG !
Объявление переменной TotalCount!
Объявление файла Cust, для которого здесь же выделяется буфер записи
Cust FILE,DRIVER('TopSpeed'),PRE(Cus)
CustKey KEY(Cus:Name)
Record RECORD
Name STRING(20)
END
END
CODE
!
Исполняемые операторы ...!*************************************
!
файл LIB01.CLW содержит:MEMBER('LIB')
!
Объявление файла Contact, для которого здесь же выделяется буфер записиContact FILE,DRIVER('TopSpeed'),PRE(Con)
ContactKey KEY(Con:Name)
Record RECORD
Name STRING(20)
END
END
AddCount PROCEDURE
CODE
TotalCount += 1
Смотри
также: DLL, NAME(установить ограничивающее выражение)
FILTER(
выражение)FILTER
Задает выражение, используемое для оценки того, включать ли запись в виртуальный файл.выражение Строковая константа, содержащая логическое выражение.
Атрибут
FILTER (PROP:FILTER) задает выражение, используемое для оценки того, включать ли запись в виртуальный файл.В выражении могут иметься ссылки на любые поля из структуры VIEW из структур JOIN любого уровня. Для того, чтобы запись была включена в виртуальный файл, все выражение в целом должно быть истиной. Выражение может включать любое допустимое языком
Clarion логическое выражение. Во время выполнения программы выражение вычисляется (точно также как процедурой EVALUATE), поэтому все входящие в выражение переменные должны быть указаны оператором BIND.Использование
MATCH с PROP:Filter и SQL базами данныхИспользование
PROP:Filter как генератора SQL-фильтров для баз данных SQL теперь поддерживает функцию преобразования MATCH(s1,s2,n), передающую результат в соответствующий SQL-фильтр для всех значений n, за исключением Match:Regular. Если Вы используете режим Match:Regular, фильтр будет оцениваться на стороне клиента точно также как все другие конвертируемые фильтры не-SQL.Другие правила преобразования:
MATCH(s1,s2,Match:Simple)
будет преобразован вs1 = s2
для всех других драйверов
SQL.MATCH(s1,s2,Match:Soundex)
будет преобразован в{fn SOUNDEX(s1)} = {fn SOUNDEX(s2)}
для всех
ODBC серверов, поддерживающих функцию SOUNDEX.MATCH(s1,s2,Match:Soundex)
будет преобразован вSOUNDEX(s1) = SOUNDEX(s2)
для
Oracle Accelerator.MATCH(s1,s2,Match:Simple + Match:NoCase)
будет преобразован в{fn UPPER(s1)} = {fn UPPER(s2)}
для
всех драйверов ODBC.MATCH(s1,s2,Match:Simple + Match:NoCase)
будет преобразован вUPPER(s1) = UPPER(s2)
для
Oracle Accelerator.MATCH(s1,s2) !Match:Wild
режимбудет преобразован в
s1 LIKE %
если параметр
s2 использует звездочку (*) илиs1 LIKE _
если параметр
s2 использует знак вопроса (?).Это допустимо для всех драйверов
SQL.Добавление режима
Match:NoCase в режим Match:Wild преобразуется в{fn UPPER(s1)} LIKE %
или {fn UPPER(s1)} LIKE _для всех драйверов
ODBC.Добавление режима
Match:NoCase в режим Match:Wild преобразуется вUPPER(s1) LIKE %
или UPPER(s1) LIKE _для
Oracle Accelerator.Пример
:BRW1::View:Browse VIEW(Members)
PROJECT(Mem:MemberCode,Mem:LastName,Mem:FirstName)
END
KeyValue STRING(20)
!
Взять только заказы начиная с 100-го для покупателя 9999ViewOrder VIEW(Customer),FILTER('Cus:AcctNumber = 9999 AND Hea:OrderNumber > 100')
PROJECT(Cus:AcctNumber,Cus:Name)
JOIN(Hea:AcctKey,Cus:AcctNumber) !
Соединить с файлом заголовковPROJECT(Hea:OrderNumber)
JOIN(Dtl:OrderKey,Hea:OrderNumber) !
Соединить с файлом накладныхPROJECT(Det:Item,Det:Quantity)
JOIN(Pro:ItemKey,Dtl:Item) !
Соединить с файлом товаровPROJECT(Pro:Description,Pro:Price)
END
END
END
END !view
CODE
BIND('KeyValue',KeyValue)
BIND(Mem:Record)
KeyValue = 'Smith'
BRW1::View:Browse{PROP:Filter} = 'Mem:LastName = KeyValue' !
указать условия фильтраOPEN(BRW1::View:Browse) !
Открыть viewSET(BRW1::View:Browse
) !и установить на начало!после фильтрования и упорядочивания
CODE !
OPEN((Customer,22h); OPEN((Header,22h); OPEN((Product,22h); OPEN(Detail,22h)
BIND('Cus:AcctNumber',Cus:AcctNumber)
BIND('Hea:OrderNumber',Hea:OrderNumber)
SET(Cus:AcctKey)
OPEN(ViewOrder)
LOOP
NEXT(ViewOrder)
IF ERRORCODE() THEN BREAK.
!
Обработать подошедшие записиEND
UNBIND('Cus:AcctNumber',Cus:AcctNumber)
UNBIND('Hea:AcctNumber',Hea:AcctNumber)
CLOSE(Header); CLOSE(Customer); CLOSE(Product); CLOSE(Detail)
Смотри
также: BIND, UNBIND, EVALUATE, SQL(добавить методы в CLASS)
IMPLEMENTS(
интерфейс)IMPLEMENTS
Добавляет дополнительные методы в класс.интерфейс Ранее определенная структура
INTERFACE, чьи методы будут определены классом, который обрабатывает указанный интерфейс.Когда класс реализует интерфейс, он наследует все методы, которые определены в интерфейсе. Класс может реализовать множество интерфейсов и опционально может определять все методы, объявленные в каждом интерфейсе, которые он реализует.
У нас теперь есть поддержка для перереализации ИНТЕРФЕЙСОВ в производных классах. В новой реализации, если дочерний класс имеет атрибут IMPLEMENTS для интерфейса уже реализованного на более высоком уровне иерархии, компилятор формирует новый интерфейс VMT. Более важным является то, что если дочерний класс имеет атрибут IMPLEMENTS для интерфейса реализованного на более высоком уровне иерархии, то не все методы интерфейса могут быть переобъявлены
. Смотри IMPLEMENTS Inheritance более подробно.
Пример 1:
MyInterface INTERFACE !
Структура интерфейсаMyProc1 PROCEDURE !
Прототип методаMyProc2 PROCEDURE !
Прототип методаEND
MyClass CLASS,IMPLEMENTS(MyInterface) !
КлассEND
MyClass.MyInterface.MyProc1 !
Объявление методаCODE
MyClass.MyInterface.MyProc2 !
Объявление методаCODE
Пример
2:MyInterface INTERFACE !
Структура интерфейсаMyProc1 PROCEDURE !
Прототип методаMyProc2 PROCEDURE,BOOL !
Прототип методаEND
MyClass CLASS,IMPLEMENTS(MyInterface) !
КлассMyProc1Worker PROCEDURE,VIRTUAL !
Прототип методаMyProc2Worker PROCEDURE,BOOL,VIRTUAL !
Прототип методаEND
MyClass.MyProc1Worker PROCEDURE
CODE
MyClass.MyProc2Worker PROCEDURE
CODE
RETURN CHOOSE(YEAR(TODAY())>2000)
MyClass.MyInterface.MyProc1 !
Объявление методаCODE
!
реализация заглушки вызывает метод класса для реальной работы:self.MyProc1Worker
return
MyClass.MyInterface.MyProc2 !
Объявление методаCODE
!
реализация заглушки вызывает метод класса для реальной работыreturn self.MyProc2Worker()
MyDerivedClass CLASS(MyClass) ! ,IMPLEMENTS(MyInterface)
не допустим!
интерфейс уже реализован родителемMyProc2Worker PROCEDURE,BOOL,DERIVED
END
MyDerivedClass.MyProc2Worker PROCEDURE
BooRt BOOL
CODE
BooRt = parent.MyProc2Worker()
IF MONTH(TODAY())=1 THEN BooRt=0.
RETURN BooRt
Смотри также:
INTERFACE, Реализация интерфейсов в производных классах
Реализация интерфейсов в производных классах
В версиях Clarion до 6.3, производный дочерний класс не мог иметь атрибута
IMPLEMENTS для тех же интерфейсов, реализованных родительским классом. При нарушении этого правила, вызывается предупреждение компилятора о дублировании метки поля в дочернем классе и, если пользователь проигнорирует предупреждение, он/она потеряет производный дочерний класс реализаций интерфейса.На практике, в текущем релизе, если предупреждение игнорируется, то вызываемый дочерний интерфейс метода на самом деле выполняет родительскую реализацию.
В Clarion версии 6.3, у нас теперь есть поддержка для повторной реализации интерфейсов в производных классах. В новой реализации, если дочерний класс имеет атрибут
INPLEMENTS для интерфейса уже реализованого в верхней части иерархии, компилятор создаст новый интерфейс VMT.Например:
IFace INTERFACE
M1 PROCEDURE()
M2 PROCEDURE()
END
Base CLASS,TYPE,IMPLEMENTS(IFace)
X PROCEDURE()
END
Child CLASS(Base),TYPE,IMPLEMENTS(IFace)
XY PROCEDURE()
END
В версии Clarion 6.3 и выше, Virtual Memory table (VMT) указанная Base.IFace содержит указатели на функции Base.IFace.M1 и Base.IFace.M2, в то время как VMT указанная Child.IFace содержит указатели на функции Child.IFace.M1 и Child.IFace.M2.
Более важно то, что если дочерний класс имеет атрибут
IMPLEMENTS для интерфейса реализованого в более высшей иерархии, то не все методы интерфейса должны быть переписаны.В примере выше, класс
Child может повторно реализовать только метод M2. Если какие-либо методы не реализованы повторно в дочернем классе, компилятор генерирует функцию "заглушки" для них, которая содержит соответствующие инструкции перехода на ближайшую реализацию, переходящую вверх по иерархии. Так, в вышеуказанном примере, если метод Child.IFace.M1 не реализован явно, компилятор для него сгенерирует код, который вызывает реализацию в родительском классе! Это огромное преимущество и гибкость в Clarion 6.3.Пример ниже демонстрирует очень простую программу, реализующую эти понятия.
PROGRAM
MAP
END
IFace INTERFACE
MyIProc PROCEDURE
MyIProc2 PROCEDURE
MyIProc3 PROCEDURE
END
Base CLASS,IMPLEMENTS(IFace)
cMyProc PROCEDURE
END
Child CLASS(Base),IMPLEMENTS(IFace) !
Допустимо только в Clarion 6.3 вышеbMyProc PROCEDURE
END
AnotherChild CLASS(Base)
IChild &IFace
END
CODE
Base.cMyProc
Child.bMyProc
Child.cMyproc !
Вызов Base.cMyProcBase.IFace.MyIProc
Child.IFace.MyIProc !
комментарии:
!
До C 6.3, если пользователь игнорирует сообщение "duplicate label warning", то!произойдет вызов родительского метода
base.iface.MyIProc. В C6.3 и выше, произойдет вызов!
реализации child.iface.MyIProc.Child.IFace.MyIProc2 !
Вызов Base.IFace.MyIProc2Child.IFace.MyIProc3 !
вызов Base.IFace.MyIProc3!
процедуры/методыBase.cMyProc PROCEDURE
CODE
MESSAGE('Base.cMyProc')
Child.bMyProc PROCEDURE
CODE
MESSAGE('Child.bMyProc')
!
реализации интерфейсаBase.IFace.MyIProc PROCEDURE
CODE
MESSAGE('Base.IFace.MyIProc')
Base.IFace.MyIProc2 PROCEDURE
CODE
MESSAGE('Base.IFace.MyIProc2')
Base.IFace.MyIProc3 PROCEDURE
CODE
MESSAGE('Base.IFace.MyIProc3')
Child.IFace.MyIProc PROCEDURE
CODE
MESSAGE('Child.IFace.MyIProc')
Важное замечание к примеру выше
. Рассмотрим определение этого класса:Child CLASS(Base),IMPLEMENTS(IFace)
bMyProc PROCEDURE
END
Класс Child на самом деле только реализует метод
ONE из интерфейса IFace , но код вызывает все три интерфейсных метода.
INNER (определить операцию внутреннего присоединения)
INNER
Наличие атрибута
INNER (PROP:INNER) говорит о том, что структура JOIN определяет “внутреннее присоединение” используемого по умолчанию “левого внешнего присоединения”.По умолчанию структура VIEW строится по принципу “левое внешнее присоединение”, когда получаются все записи первичного файла VIEW-структуры независимо от того, содержит ли вторичный файл, определенный в структуре JOIN, какие-нибудь связанные записи или нет. Задание у оператора JOIN атрибута INNER приводит к тому, что из первичного файла выбираются только те записи, у которых есть по крайней мере одна связанная запись во вторичном файле. Внутреннее присоединение обычно более эффективно, нежели внешнее.
PROP:INNER
это множественное свойство VIEW, указывающего наличие или отсутствие атрибута INNER в указанном JOIN. Каждый из элементов массива возвращает единицу (“1”), если JOIN имеет атрибут INNER и – пустую строку (‘’), если не имеет. Присоединения (joins) нумеруются внутри VIEW начиная с 1 в том порядке, в котором объявлены в этой структуре. (Только для чтения)Пример
:AView VIEW(BaseFile)
JOIN(ParentFile,'BaseFile.parentID = ParentFile.ID') !JOIN 1
JOIN(GrandParent.PrimaryKey, ParentFile.GrandParentID) !JOIN 2
END
END
JOIN(OtherParent.PrimaryKey,BaseFile.OtherParentID),INNER !JOIN 3
END
END
! AView{PROP:Inner,1}
возвращает ''! AView{PROP:Inner,2}
возвращает ''! AView{PROP:Inner,3}
возвращает '1'ViewOrder VIEW(Customer),ORDER('-Hea:OrderDate,Cus:Name')
PROJECT(Cus:AcctNumber,Cus:Name,Cus:Zip)
JOIN(Hea:AcctKey,Cus:AcctNumber),INNER !
Внутреннее присоединение на файле,!записи из которого представлены в
!Header
PROJECT(Hea:OrderNumber,Hea:OrderDate) !
отбирает только покупателей с!
заказамиJOIN(Dtl:OrderKey,Hea:OrderNumber),INNER !
Внутреннее присоединение на файле,!записи из которого представлены в Detail
PROJECT(Det:Item,Det:Quantity) !
является естественным и более!
эффективнымJOIN(Pro:ItemKey,Dtl:Item),INNER !
Внутреннее присоединение на файле ProductPROJECT(Pro:Description,Pro:Price) !
является естественным и более!
эффективнымEND
END
END
END
Смотри
также: JOIN(точно определяет связи CLASS в проекте)
LINK(
связываемый файл, [ флаг ] )LINK
Идентифицирует файл, который будет добавлен в список связей текущего проекта.связываемый файл
Строковая константа, содержащая имя файла (без расширения OBJ), связываемого с проектом. Обычно это тоже самое, что и параметр MODULE, но с уточненным именем .LIB или .OBJ файла.флаг Численная константа, метка соответствия или определение системы проекта (Project system define), которая указывает, активен ли атрибут. Если значение этого параметра равно нулю или пропущено, то атрибут неактивен, как если бы он вообще отсутствовал. Если значение флага отличается от нуля – атрибут активен.
Атрибут
LINK структуры CLASS задает имя связываемого файла, который будет добавлен в список для компиляции проекта. LINK действителен только в структуре CLASS.Пример:
OneClass CLASS,MODULE('OneClass'),LINK('OneClass',1) !
Связь в OneClass.OBJLoadIt PROCEDURE
ComputeIt PROCEDURE
END
Смотри
также: CLASS, MEMBER, MODULE(указать модуль исходного текста для методов класса)
MODULE(
исходный файл)MODULE
исходный файл Строковая константа. Если исходный файл содержит исходный текст на языке Clarion, то эта константа содержит имя файла (без расширения), в котором находятся процедуры. Если исходный файл представляет собой внешнюю библиотеку, то эта строка должна содержать произвольный уникальный идентификатор.
Атрибут
MODULE структуры CLASS указывает имя MEMBER-модуля или внешней библиотеки, в которой содержатся определение процедур для методов данного класса. Атрибут MODULE допустим только для структуры CLASS.Пример:
OneClass CLASS,MODULE
(‘OneClass’) !Определение методов находится в OneClass.CLWLoadIt PROCEDURE !
Прототип процедуры LoadItComputeIt PROCEDURE !
Прототип процедуры ComputeItEND
Смотри
также: CLASS, MEMBER, LINK, Прототипы процедур
NAME(
[имя] )NAME
Указывает внешнее имя.имя Строковая константа включающая внешнее имя или метку статической строковой переменной. Она может быть объявлена как глобальная, модульная или локальная переменная с атрибутом
STATIC.Атрибут
NAME (PROP:NAME) задает внешнее имя переменной. Он полностью независим от атрибута EXTERNAL - между ними нет никакой связи, хотя оба эти атрибута могут использоваться с одной переменной.Атрибут NAME может находиться в прототипе процедуры, в операторах FILE, KEY, INDEX, MEMO, в объявлении любого поля в структуре FILE, в объявлении любого поля в структуре QUEUE или в объявлении любой отдельной переменной. Этот атрибут имеет различное толкование в зависимости от того, где он применяется.
Использование в прототипах процедур
NAME
может быть указан в прототипе процедуры. Константа представляет собой внешнее имя, используемое компоновщиком для того, чтобы идентифицировать процедуру или функцию из внешней библиотеки.Использование в переменных
Атрибут NAME может использоваться для любой переменной, объявленной вне какой-либо структуры. В этом случае атрибут обеспечивает внешнее имя, используемое компоновщиком для того, чтобы идентифицировать переменную, объявленную во внешней библиотеке. Если переменная к тому же имеет атрибут EXTERNAL, то она объявляется как общая (public) переменная во внешней библиотеке с соответствующим механизмом выделения памяти. Без атрибута EXT
ERNAL память переменной выделяется в Clarion-программе, а сама она объявляется как внешняя переменная во внешней библиотеке.Использование в файлах
Атрибут NAME, относящийся к объявлению файла, указывает имя файла данных для файлового драйвера. Если имя не содержит обозначения диска и каталога, то подразумеваются текущий диск и каталог. Если опущено расширение, то подразумевается используемое по умолчанию для данного файлового драйвера.
Для некоторых файловых драйверов предполагается, что ключи, индексы или MEMO поля находятся в отдельных файлах. Поэтому атрибут NAME может также употребляться в операторах KEY, INDEX или MEMO. Атрибут NAME без параметров предполагает в качестве имени метку оператора, в котором он используется (включая любой указанный префикс).
NAME
может использоваться при объявлении любого поля внутри структуры RECORD (в этом случае параметр имя должен быть константой). Он обеспечивает файловый драйвер именем поля, как это, возможно, принято в файловой системе данного драйвера.Вы можете динамически изменять имя поля внутри структуры
FILE используя свойство PROP:NAME как массив. Номер элемента массива указывает порядок расположения полей внутри файла.Атрибут
NAME считается частью файловой структуры, и следует позаботиться о том, чтобы переменные, использующие отдельный исполняемый процесс и имеющие атрибут NAME, не ссылались на файлы, не использующие отдельный исполняемый процесс.Например
:FileName STRING(255)
TFileName STRING(255),THREAD
File FILE,NAME(TFileName) !
НеправильноFile FILE,NAME(FileName) !
ПравильноFile FILE,NAME(TFileName),THREAD !
ПравильноFile FILE,NAME(FileName),THREAD !
ПравильноИспользование в очередях
Атрибут NAME, использующийся для переменных, объявленных в структуре QUEUE, указывает внешнее имя для обработки очередей. Имя обеспечивает альтернативный метод адресации переменных в очереди, в которой используются операторы
SORT, GET, PUT и ADD.Пример
:PROGRAM
MAP
MODULE('External.Obj')
AddCount PROCEDURE(LONG),LONG,C,NAME('_AddCount') !
Функция на C именем '_AddCount'END
END
Cust FILE,PRE(Cus),NAME(CustName) !
Имя файла в переменной CustNameCustKey KEY('Name'),NAME('c:\data\cust.idx') !
Объявить ключ cust.idxRecord RECORD
Name STRING(20) !
По умолчанию внешнее имя 'Cus:Name'END
END
SortQue QUEUE
Field1 STRING(10),NAME('FirstField') !
Имя поля сортировки таблицыField2 LONG,NAME('SecondField') !
Имя поля сортировки таблицыEND
CurrentCnt LONG,EXTERNAL,NAME('Cur') !
Переменная объявлена как public во внешней!
библиотеке 'Cur'TotalCnt LONG,NAME('Tot') !
Переменная объявлена как внешняя! во внешней библиотеке '
Tot'CODE
OPEN(Cust)
Cust{PROP:NAME,1} = 'Fred' !
поле Cus:Name теперь называется 'Fred'Смотри
также: Прототипы процедур, QUEUE, SORT, GET, PUT, ADD, FILE, KEY, INDEX, EXTERNAL
NOCASE (независимость ключа или индекса от регистра букв)
NOCASE
Атрибут
NOCASE (PROP:NOCASE) в объявлении ключа или индекса делает независящей от ACSII регистра букв последовательность упорядочения ключа или индекса. Все буквы в значениях ключа при записи в файл ключей преобразуются в прописные. Это преобразование не влияет на регистр букв в полях записи в файле данных. Не влияет оно и на символы, не являющиеся буквами.Пример:
Names FILE,DRIVER('Clarion'),PRE(Nam)
NameKey KEY(Nam:Name),NOCASE !
Объявить ключ по полю имя, любой регистр буквNbrKey KEY(Nam:Number) !
Объявить ключ по полю номерRec RECORD
Name STRING(20)
Number SHORT
END
END
Смотри
также: INDEX, KEY
OEM (установить поддержку международной кодировки)
OEM
Атрибут
OEM (PROP:OEM) указывает, что данный файл содержит строковые данные не на английском языке, которые были сохранены программами DOS или должны быть прочитаны в программах DOS. Эти строки автоматически перекодируются из кодировки OEM ASCII, в которой они содержатся в файле в набор символов ANSI, в котором они отображаются в Windows. Перед выводом на диск все строковые данные в записи файла автоматически перекодируются из кодировки ANSI в кодировку OEM ASCII.Конкретный набор символов OEM ASCII, используемый при перекодировании, берется из кодовой страницы DOS, загруженной драйвером
country.SYS. Это “привязывает” файл данных к конкретному языку, использующему эту кодовую страницу и значит, что эти данные нельзя использовать на компьютере, на котором загружена другая кодовая страница. Этот атрибут может поддерживаться не всеми файловыми системами. За уточнением обращайтесь к документации по конкретному файловому драйверу.Пример
:Cust FILE,DRIVER('TopSpeed'),PRE(Cus),OEM !
Содержит не английские строкиCustKey KEY(Cus:Name)
Record RECORD
Name STRING(20)
END
END
Screen WINDOW('Window')
ENTRY(@S20),USE(Cus:Name)
BUTTON('&OK'),USE(?Ok),DEFAULT
BUTTON('&Cancel'),USE(?Cancel)
END
CODE
OPEN(Cust) !
Открыть файл CustSET(Cust); NEXT(Cust) !
Прочитать запись, строки в кодировке ASCII! автоматически перекодируются в
ANSIOPEN(Screen) !
Открыть окно и вывести данные в коде ANSIACCEPT
CASE FIELD()
OF ?Ok
CASE EVENT()
OF EVENT:Accepted
PUT(Cust) !
Вывести запись, строки в кодировке ANSI!автоматически перекодируются в OEM ASCII
!по загруженной в DOS кодовой странице
BREAK
END
END
END
CLOSE(Screen);CLOSE(Cust)
Смотри также:
Файлы настройки среды, LOCALEOPT (исключить нулевые значения ключа или индекса)
OPT
Атрибут
OPT (PROP:OPT) позволяет исключить из индекса или ключа элементы для тех записей, в которых все поля, составляющие ключ или индекс, имеют “пустое” значение. В контексте использования этого атрибута “пустым” значением является нуль для числовых полей и заполненное пробелами (20h) строковое поле.Пример
:Names FILE,DRIVER('Clarion'),PRE(Nam) !
Объявить структуру файлаNameKey KEY(Nam:Name),OPT
!Объявить ключ по полю имя, не допуская пустых именNbrKey KEY(Nam:Number),OPT !
Объявить ключ по номеру, не допуская нулевых номеровRec RECORD
Name STRING(20)
Number SHORT
END
END
Смотри
также: INDEX, KEY
ORDER (выражение, определяющее порядок сортировки)
ORDER(
список выражений)ORDER
Задает список выражений, используемый при сортировке записей виртуального файла.список выражений Строковая константа содержащая одно или более выражений. Каждое выражение в списке должно отделяться запятой.
Атрибут
ORDER (PROP:ORDER) задает список выражений, используемый при сортировке записей виртуального файла. Выражения в списке вычисляются слева направо; приоритет сортировки убывает слева направо. Выражение, которому предшествует знак минус (-) определяет убывающую последовательность сортировки.В выражении могут быть ссылки на любые поля структуры VIEW с любых уровней структур JOIN. Выражения в списке могут содержать в себе любые допустимые в языке Clarion выражения. Во время выполнения программы выражение вычисляется (точно так же как процедурой EVALUATE), поэтому все входящие в выражение переменные должны быть указаны оператором BIND.
8
Для систем не являющихся файловыми системами
SQL, виртуальный файл использует такие ключи, хранящие один отсортированный “сегмент”, чтобы по возможности сортировались только группы записей имеющих одинаковые значения ключей. Поэтому дополнительные поля сортировки в верхней части ключа могут быть довольно эффективны.Для
SQL систем PROP:SQLOrder это только для SQL, эквивалентен PROP:ORDER. Если первым знаком выражения является знак плюс (+), то выражение присоединяется к существующему выражению порядка, что справедливо для обоих свойств. Если первым знаком выражения является минус (-), то существующее выражение присоединяется к этому выражению, что справедливо для PROP:SQLOrder. Если первый знак не является плюсом или минусом, то новое выражение заменяет собой существующее.Пример:
!
Порядок сортировки: по убыванию даты, затем по фамилии покупателя!(
в рамках каждой датыViewOrder VIEW(Customer),ORDER('-Hea:OrderDate,Cus:Name')
PROJECT(Cus:AcctNumber,Cus:Name,Cus:Zip)
JOIN(Hea:AcctKey,Cus:AcctNumber) !
Присоединить файл HeaderPROJECT(Hea:OrderNumber,Hea:OrderDate)
JOIN(Dtl:OrderKey,Hea:OrderNumber) !
Присоединить файл DetailPROJECT(Det:Item,Det:Quantity)
JOIN(Pro:ItemKey,Dtl:Item) !
Присоединить файл ProductPROJECT(Pro:Description,Pro:Price)
END
END
END
END
CODE
ViewOrder{PROP:ORDER} = '-Hea:OrderDate,Pro:Price-Det:DiscountPrice'
!
Порядок сортировки по величине скидки внутри каждой даты!ABC
реализация примера PROP:SQLORDER!Для списка просмотра, после открытия файлов и окна
BRW1::View:Browse{PROP:SQLOrder} = ‘Phone’
!где Phone имя столбца в базе данных SQL
!Для отчетов, после открытия файлов и окна:
Process:View{PROP:SQLOrder} = ‘au_lname’
!где au_lname столбец в базе данных SQL
Смотри также:
BIND, UNBIND, EVALUATE
OVER (совместное использование памяти)
OVER(
переменная)OVER
Допустить обращение к одной области памяти двумя различными способами.переменная Метка переменной, которая уже занимает ту память, которая должна совместно использоваться.
Атрибут
OVER позволяет к одному участку памяти адресоваться двумя различными способами. Переменная, объявленная с атрибутом OVER должна быть не больше той, поверх которой она объявляется (меньше - может быть).Можно объявить переменную поверх переменной, которая является частью списка параметров, переданного в процедуру.
Переменная внутри структуры GRОUР не может объявляться поверх переменной не входящей в эту структуру.
Пример:
SomeProc PROCEDURE(PassedGroup
) !Процедуре передается параметр GROUPNewGroup GROUP,OVER(PassedGroup
) !Переобъявить переданный параметр GROUPField1 STRING
(10) !Предупреждение компилятора о том, чтоField2 STRING(2) ! NewGroup
не должна быть большеEND !
чем PassedGroupCustNote FILE,PRE(Csn) !
Объявить файл CustNoteNotes MEMO(2000) !
мемо полеRecord RECORD
CustID LONG
END
END
CsnMemoRow STRING(10),DIM(200),OVER(Csn:Notes)
!
К полю Csn:Notes можно обращаться как к целому! или по частям по 10 байт
Смотри также:
DIM
OWNER (объявить пароль для шифрования данных)
OWNER(
пароль)OWNER
Задает пароль для шифрования данных.пароль Строковая константа или переменная.
Атрибут
OWNER (PROP:OWNER) задает пароль, который используется для шифрования данных атрибутом ENCRIPT. Если пароль не совпадает с паролем, реально использующимся в шифрованном файле, то появится ошибка “Invalid Data File”.Использование атрибута
OWNER без соответствующего атрибута ENCRYPT позволено в некоторых системах баз данных.Если файл был объявлен без атрибута
THREAD, переменная, использующая атрибут OWNER, также должна быть объявлена без атрибута THREAD.Пример
:Customer FILE,DRIVER('Clarion'),OWNER('abCdeF'),ENCRYPT !
Зашифровать данные с помощью!ключевого слова
"abCdeF"Record RECORD
Name STRING(20)
END
END
Смотри
также: ENCRYPT, EXTERNALзадать префикс)
PRE(
[ префикс ] )PRE
Обеспечивает префикс для переменных в составных структурах данных.префикс Допустимы символы букв, цифр от 0 до 9 и символ подчеркивания. Префикс должен начинаться с буквы или символа подчеркивания. Хотя префикс может быть длинным, по традиции он состоит из 1-3-х букв.
Атрибут
PRE обеспечивает префикс для структур FILE, QUEUE, GROUP, REPORT или ITEMIZE. Он также допустим для объявлений типа LIKE для обеспечения отличающихся префиксов, когда LIKE объявляет копию другой составной структуры данных.PRE
используется для того, чтобы различать одноименные переменные в различных структурах. При использовании в исполняемых операторах, операторах присваивания и в списках параметров префикс присоединяется к имени переменной с помощью двоеточия (префикс:имя).Для идентификации одноименных переменных, которые могут быть объявлены в структурах, не имеющих атрибута PRE, используется другой, более гибкий метод - синтаксис уточнения имен. При упоминании в исполняемых операторах, присвоениях и списках параметров к имени переменной через двоеточие спереди присоединяется имя содержащей данное поле структуры (GroupName:Label).
ЛАВА
Пример
:MasterFile FILE,DRIVER('Clarion'),PRE(Mst) !
Объявить структуру главного файлаRecord RECORD
AcctNumber LONG !
ссылаться как на Mst:AcctNumber или MasterFile.AcctNumberEND
END
Detail FILE,DRIVER('Clarion'),PRE(Dtl) !
Объявить структуру файла DetailRecord RECORD
AcctNumber LONG !
ссылаться как на Dtl:AcctNumber или Detail.AcctNumberEND
END
SaveQueue QUEUE,PRE(Sav)
AcctNumber LONG !
ссылаться как на Sav:AcctNumber или SaveQueue.AcctNumberEND
G1 GROUP,PRE(Mem) !
Объявить переменные в памятиMessage STRING
(30) !с префиксом MemEND
G2 LIKE(G1),PRE(Me
2) !Другая GROUP как первая включающая такие жеCODE
!переменные используя префикс "Me2"IF Dtl:AcctNumber <> Mst:AcctNumber !
Это новый счетMem:Message = 'New Account' !
Вывести сообщениеMe2:Message = 'Variable in LIKE group'
END
IF Detail.AcctNumber <> Masterfile.AcctNumber !
такое же выражениеG1.Message = 'New Account' !
Вывести сообщениеG2.Message = 'Same Variable in LIKE group'
END
Смотри также:
Зарезервированные слова, Синтаксис уточнения имен
PRIMARY (установить первичный ключ)
PRIMARY
Атрибут
PRIMARY (PROP:PRIMARY) указывает, что данный ключ является уникальным ключом содержащимся в каждой записи файла и для него недопустимы “пустые” значения любого из составляющих его полей. Это определение “по Кодду” первичного ключа в теории реляционных баз данных.Пример
:Names FILE,DRIVER('TopSpeed'),PRE(Nam) !
Объявить структуру файлаNameKey KEY(Nam:Name),OPT !
Объявить ключ Name, пробельные значения недопустимыNbrKey KEY(Nam:Number),PRIMARY !
Объявить файл Number как первичный ключRec RECORD
Name STRING(20)
Number SHORT
END
END
Смотри также:
KEY
PRIVATE (переменные класса доступны только в пределах модуля)
PRIVATE
Атрибут
PRIVATE указывает, что переменная для которой он задан, доступна только для процедур определенных внутри исходного модуля, содержащего методы этой структуры CLASS (независимо члены класса или нет). Таким образом данные инкапсулируются от других классов.Атрибут
PRIVATE также допустим для статических (потоковых и непотоковых) переменных, объявленных вне структуры класса. Если статическая переменная объявлена с атрибутом PRIVATE, компилятор воспримет ее без общего внешнего имени. Поэтому она может быть использована только процедурами, объявленных в том же самом исходном модуле.Пример
:OneClass CLASS,MODULE('OneClass.CLW'),TYPE
PublicVar LONG !
Объявить общую переменнуюPrivateVar LONG,PRIVATE !
Объявить “публичную” переменнуюBaseProc PROCEDURE(REAL Parm) !
Объявить общий методEND
TwoClass OneClass !
Экземпляр класса OneClassCODE
TwoClass.PublicVar = 1 !
Правильное присвоениеTwoClass.PrivateVar = 1 !
Неправильное присвоение!
Файл OneClass.CLW содержит:MEMBER()
MAP
SomeLocalProc PROCEDURE
END
OneClass.BaseProc PROCEDURE(REAL Parm)
CODE
SELF.PrivateVar = Parm !
Правильное присвоениеSomeLocalProc PROCEDURE
CODE
TwoClass.PrivateVar = 1 !
Правильное присвоениеСмотри также:
CLASSROTECTED (установить переменную частной в CLASS или порожденном CLASS)
PROTECTED
Атрибут
PROTECTED указывает на то, что переменная, которой он назначен, видна только для тех PROCEDURE, которые объявлены в той же самой структуре CLASS (методах CLASS) или в любом CLASS, порожденном из того CLASS, в котором она объявлена. Это изолирует данные от любого внешнего кода для указанного класса или порожденных от него классов.Смысл в использовании атрибута
PROTECTED – обеспечить уровень инкапсуляции между общими и частными объявлениями. Все защищенные данные и методы доступны для использования внутри классов, в которых они объявлены и производных от них классах, но недоступны для внешнего от указанного класса исполняемых операторов.Можно считать их “полуприватными”.
Пример:
OneClass CLASS,MODULE('OneClass.CLW'),TYPE
PublicVar LONG !
Объявление Общей переменнойProtectedVar LONG,PROTECTED !
Объявление защищенной переменнойBaseProc PROCEDURE(REAL Parm) !
Объявление Общего методаEND
TwoClass OneClass !
Экземпляр OneClassCODE
TwoClass.PublicVar = 1 !
Правильное назначениеTwoClass.ProtectedVar
= 1 ! Правильное назначение, неправильно, если PRIVATE! OneClass.CLW
содержит:MEMBER()
MAP
SomeLocalProc PROCEDURE
END
OneClass.BaseProc PROCEDURE(REAL Parm)
CODE
SELF.ProtectedVar = Parm !
Правильное назначениеSomeLocalProc PROCEDURE
CODE
TwoClass.ProtectedVar = 1 !
Правильное назначениеСмотри также:
CLASS
RECLAIM (использовать пространство удаленных записей)
RECLAIM
Атрибут
RECLAIM (PROP:RECLAIM) указывает, что файловый драйвер помещает новые записи в файл на место, ранее занимаемое удаленными теперь записями (если, конечно такое пространство имеется). В противном случае записи добавляются после последней записи файла. Реализация этого механизма зависит от файлового драйвера и не во всех файловых системах может быть осуществлена.Пример
:Names FILE,DRIVER('Clarion'),RECLAIM !
Использовать место удаленных записейRecord RECORD
Name STRING(20)
END
END
статическая локальная переменная)
STATIC
Атрибут
STATIC говорит о том, что переменной, группе или данных буфера очереди, объявляемой в процедуре, должна распределяться статическая память, а не память в стеке. Этот атрибут позволяет любому значению, содержащемуся в такой локальной переменной или данным буфера очереди, возобновляться при переходе от одной копии процедуры или подпрограммы к другой. Что касается структуры QUEUE, в статической памяти могут располагаться только данные ее буфера – записям очереди всегда динамически выделяется память из “кучи”.Пример:
SomeProc PROCEDURE
SaveQueue QUEUE,STATIC
!Данные буфера очереди в статической памятиField1 LONG
!Значение сохраняется междуField2 STRING
! ! вызовами процедурEND
AcctFile STRING(64),STATIC !STATIC
нужен для использования этой!
переменной с атрибутом NAMETransactions FILE,DRIVER('Clarion'),PRE(TRA),NAME(AcctFile)
AccountKey KEY(TRA:Account),OPT,DUP
Record RECORD
Account SHORT !
Учетный кодDate LONG !
Дата транзакцииAmount DECIMAL(13,2) !
Сумма сделкиEND
END
Смотри также:
Объявление данных и распределение памяти(указать отдельный буфер расположения в памяти)
THREAD
Атрибут
THREAD указывает, что переменной, файлу, группе, очереди или классу память распределяется отдельно для каждого исполняемого процесса в программе. Таким образом значение этой переменной зависит от того, какой процесс выполняется.Переменной с атрибутом THREAD должна выделяться статическая память, поэтому локальные данные с таким атрибутом автоматически рассматриваются как статические. Этот атрибут влечет за собой дополнительные издержки времени выполнения, особенно для глобальных данных и данных модуля. Поэтому его следует использовать только когда это абсолютно необходимо.
В приложениях, использующих несколько библиотек
DLL, в случае если, атрибут THREAD объявлен в любой из вышеуказанных допустимых типов, любая ссылка на эти типы в связанной программе или другой DLL также должна содержать атрибут THREAD.Использование в группах и переменных
Атрибут THREAD указывает, что статической переменной память распределяется отдельно для каждого исполняемого процесса в программе. Таким образом значение этой переменной зависит от того, какой процесс выполняется. Как только начат новый исполняемый процесс, для него создается и инициализируется пробелами или нулем новая копия этой переменной (если только не указан атрибут AUTO).
Использование в файлах
Атрибут THREAD
(PROP:THREAD – допустим только для файлов) для объявлений файлов указывает, что память для буфера записи, управляющий блок файла и другие элементы структуры распределяется отдельно для каждого исполняемого процесса в программе. Таким образом значения, содержащиеся в буфере и другие элементы файла зависят от того, какой процесс выполняется. При закрытии процесса память, выделенная для буфера записи файла, управляющего блока файла и других элементов структуры файла, освобождается.Экземпляры файлов с атрибутом
THREAD считаются независимыми друг от друга. Однако файл должен открываться и закрываться для каждого нового экземпляра.Использование в очередях
Атрибут THREAD
для очереди указывает, что память для буфера статической очереди распределяется отдельно для каждого исполняемого процесса в программе. Таким образом значения, содержащиеся в буфере, зависят от того, какой процесс выполняется. Как только начат новый исполняемый процесс, для него создается новая, собственная копия очереди.Пример
:PROGRAM
MAP
Thread1 PROCEDURE
Thread2 PROCEDURE
END
Names FILE,DRIVER('Clarion'),PRE(Nam),THREAD !
Файл раздельно используемый процессамиNbrNdx INDEX(Nam:Number),OPT
Rec RECORD
Name STRING(20)
Number SHORT
END
END
GlobalVar LONG,THREAD
!Копия GlobalVar в каждом из исполняемых потоковCODE
START(Thread1)
START(Thread2)
Thread1 PROCEDURE
LocalVar LONG,THREAD
!Локальная переменная отдельная для каждого процесса!(автоматически получает атрибут
STATIC)CODE
OPEN(Names) !OPEN
создает новую копию записиSET(Names
) !содержащую 1-ю запись в файлеNEXT(Names)
Thread2 PROCEDURE
SaveQueue QUEUE,THREAD
!Статическая очередь, буфер которой в отдельном процессеName STRING(20)
Number SHORT
END
CODE
OPEN(Names) !OPEN
создает другую копию буфера записиSET(Names
) !содержащую последнюю запись в файлеPREVIOUS(Names)
Смотри также:
START, Объявление данных и распределение памяти, STATIC, AUTO
TYPE
Атрибут
TYPE создает для группы, очереди или класса (поименованная структура) “определение типа”. Метка поименованной структуры может быть использована как тип данных для определения других подобных групп очередей или классов (или вы можете использовать LIKE). TYPE может быть также использован для определения поименованных структур передаваемых процедурам, что позволяет принимающей процедуре напрямую обращаться к компонентам определения типа, используя синтаксис уточнения имен.Группе, очереди или классу с атрибутом TYPE память не распределяется. Данным для класса или группы с атрибутом TYPE память также не выделяется, методы объявленные в классе должны быть определены для использования любыми последующими объектами, объявленные с таким типом. Атрибуты
EXTERNAL и DLL тут неуместны.Когда определение типа используется для передачи поименованных структур как параметр в процедуру, это позволяет процедуре непосредственно адресоваться к отдельным полям переданной очереди, используя синтаксис уточнения имен. Это предпочтительный метод для адресации к компонентам переданной структуры.
Есть еще один легальный способ для адресации к компонентам переданной структуры. Объявление параметра в операторе PROCEDURE (не прототип) устанавливает локальный префикс для передаваемой очереди поскольку он указывает имя, используемое в данной процедуре, для передаваемой очереди. Например, PROCEDURE(LOC:Passed
Queue) объявляет, что процедура использует для непосредственного обращения к полям-компонентам, передаваемой в качестве параметра структуры QUEUE, префикс LOC: (с именами отдельных полей, объявленными в определении типа). Однако, предпочтительнее использовать Синтаксис Уточнения имени – локально прибавленные префиксы поддерживаются только для обратной совместимости.Пример:
MAP
MyProc1 PROCEDURE(PassQue
) !передаваемая очередь определена также как PassGroupEND
PassQue QUEUE,TYPE
!Определение типа для передаваемой очередиFirst STRING(20) !
первое имяMiddle STRING(1) !
средний инициалLast STRING(20) !
последнее имяEND
NameQue QUEUE(PassQue) !
имя очереди—такая же структура как PassQueEND
!конец объявления очередиCODE
MyProc1(NameQue
) !Вызов процедуры передающей NameQue как параметрMyProc1 PROCEDURE(PassedQue
) !Процедура получает параметр QUEUELocalVar STRING(20)
CODE
LocalVar = PassedQue.First !
присвоить NameQue.First в LocalVar из параметраСмотри также:
Уточнение имен, Списки параметров в прототипах, CLASS, GROUP