$$START!
VI. Дополнительно |
VI. Additionally |
VI. 1. Локализация строковых ресурсов |
VI. 1. Localization of string resources |
| AL-IV
поддерживает механизм локализации строк с помощью псевдо-функций
вида _идентификатор.
Для строки это выглядит как вызов функции, например, Но вызовом функции данная конструкция не является. Она лишь сообщает компилятору о том, что строку "Red square" следует поместить в массив локализуемых строк, индекс строки в этом массиве запомнить и использовать для извлечения строки из этого массива. Фактически, при этом может быть извлечена другая строка, записанная в этот массив вместо исходной строки "Red square" в результате работы функций локализации. Например, это может быть строка "Красный квадрат". Все имена таких строковых ресурсов должны быть уникальными в пределах класса. В качестве стандартного API для управления
локализацией предлагается класс |
The AL-IV programming language
supports localization of strings via preudo-functions in form of This construction looks like a function call but it is not a call to a function. But it tells to a compiler that a sting "Red square" should be placed into an array of localized strings, remember its index in the array and use it to extract the string from the localization array. Actually, another string can be extracted, if it was replacing the original one in result of working of localization operations. All the names of such string resources (pseudo-functions) should be unique in a class. A special class |
|
При использовании класса Метод |
When using the class The method Localize has an additional parameter Prefix which allows translating not all the strings, but only those having names starting from a certain prefix (the Prefix is provided without leading underscore character). An empty string means translating all the strings independently of resource names. |
|
При обращении к методу Localize
первым делом вызывается метод |
When the Localize method is called it is first is calling a
method |
|
Местом хранения языковых файлов по умолчанию являются либо
директория, в которой запускается приложение, либо (если запись туда
невозможна) - специальная директория для данных приложения. Либо,
имеется возможность явно указать такую директорию (метод
|
By default a directory where an application is located is used
as a place to store language files. Or if it is impossible to write
there a special application data directory is used. Or it is possible to
set such directory explicitly (calling |
|
Важно, что если в процессе разработки были добавлены новые
транслируемые строки, то они распространяются не только на исходный
файл, сохраняемый из приложения при вызове
|
It is important that if new strings to translate were added
while developing an application, then these are spread not only to an
original language file stored by |
VI. 2. Локализация ключевых слов языка |
VI. 2. Localization of the language keywords |
| AL-IV поддерживает возможность трансляции ключевых слов самого языка с использованием любого другого письменного языка. При этом частично используется техника локализации строк (см. выше). Все ключевые слова канонической (английской) версии языка размещаются в текстовом файле Default_.lng в директории с исходными текстами компилятора. Достаточно скопировать этот файл и переименовать, например, в Klingon_KL.lng, после чего заменить строки на свои, и становится возможно использовать ключевые слова на соответствующем языке. Ключевые слова в языковом файле имеют имена, начинающиеся буквой K, и в основном сосредоточены в секции [{Translation_to_canonical_keyword}]. Для использования в классе национальных ключевых слов, класс должен начинаться со спецификации языка вида ['KL'] или [Language='KL'], после которой первое же ключевое слово должно быть записано уже на указанном языке. Например: |
The AL-IV supports translation of its keywords from any human language. For this purpose a localization technique (from above section) is used partially. All the English keywords are stored in a text file Default_.lng in a directory with source files of the compiler. It is sufficient to copy this text file, rename it e.g. to Klingon_KL.lng and replace string values from English to some other. Language keywords have names starting from the letter "K" and these are mainly in the section [{Translation_to_canonical_keyword}]. To use national keywords in your code, a class should be started from a specification ['KL'] or [Language='KL'], following which the first keyword (CLASS) is already translated into the language specified. |
['RU'] КЛАСС
{Привет_мир},
НЕТЕСТИРОВАН : |
|
| В связи с тем, что язык перевода может содержать ряд морфологических особенностей (падежи, спряжения, связки, предлоги и т.д.), специально для перевода ключевых слов разработаны правила, позволяющие более гибко сопоставлять более одного национального варианта для каждого ключевого слова, и даже использовать два отделенных пробелами идентификатора вместо одного ключевого слова. Для этого в качестве перевода может использоваться более одного
словосочетания, при этом словосочетания разделяются запятыми. Внутри
словосочетания (которое может быть одним словом) вертикальный
разделитель разделяет несколько возможных окончаний, которые могут
продолжить основной корень. Например, - позволяет использовать вместо THIS слова и словосочетания:
Примечание: в языке AL-IV ключевое слово THIS бывает необходимо в основном в двух случаях:
|
Since a translation language can have some word morph rules or have some variations depending on a lexical context, especially for keywords it is allowed to relate to a single canonical keyword more then a single identifier. A translation can have a form of several word sequences comma separated, where each sequence have a form root|suffix1|fuffix2|..., and any suffix can have a space or start from a space. In result, all the words root, rootsuffix1, rootsuffix2, ... are corresponding to the keyword specified (and a space in a suffix means that two identifiers spaces/tabs separated are treated as the target keyword, too). |
| Вместе с ключевыми словами локализуются кодированные символы (#NL, #TAB и т.п.), а так же встроенные псевдо-функции (.Len, .Str, .Index и др.) Но в языке имеется так же возможность упростить перевод любых ранее изготовленных классов на национальные языки. Для этого для транслируемого класса создаётся класс-зеркало на соответствующем языке, с единственным модификатором в заголовке TRANSLATION OF {Class_name}. Он должен содержать только переводы наименований для полей, функций (и их параметров), перечислений, записей, констант. Переименования помещаются в соответствующие секции. Например: |
Together with the language
keywords, encoded characters are translated (#NL, #TAB etc.) and some
embedded pseudo-functions such as (.Index, .Len, .Str). And it is
allolwed to translate whole classes to national languages. To do so, for
a translating class a special mirror class is created which have a
single modifier |
['RU'] |
|
| Теперь достаточно включить такой класс в список импорта, и использовать переведённые наименования его функций, методов, полей и т.д. - с использованием национальных букв / иероглифов / рун / литер / клиньев / каракулей / узелков и т.п. |
Then it is sufficient to include such translation class into import and call its methods, functions, fields etc. using translated names. |
| Примечание для русскоязычных читателей. Возможность по русификации (или точнее, произвольной локализации) предоставляется как механизм, позволяющий развивать навыки программирования в любом возрасте, без необходимости начинать с изучения английского языка. Несмотря на довольно большой список слов в словаре, основа языка АЛФОР требует значительно меньше важных ключевых слов для того, чтобы можно было начать писать свой код или понимать уже написанный. Например, класс для вычисления вещественных корней квадратного уравнения: |
|
['RU'] КЛАСС
{Квадратное_уравнение},
НЕТЕСТИРОВАН: |
|
| Формат класса для перевода на другой язык, в форме диаграммы: |
A class format for a translation class, in form of a diagram: |
VII. 3. STORE - скрытые параметры |
VI. 3. STORE - hidden parameters |
| Модификатор STORE для метода создаёт скрытый (для вызывающей стороны) целочисленный параметр, значение которого сохраняется на стороне вызывающего объекта. В модификаторе задаётся имя параметра, как его видит функция, и может быть задано первоначальное значение: , STORE(Имя = значение) |
A modifier STORE for a method creates hidden (for a caller side) integer parameter which value is stored on a caller side. A name of a parameter is specified in parenthesis, and also its initial value can be specified additionally: , STORE(Name = value) |
| Для каждого вызова метода в вызывающем классе создаётся скрытое целочисленное поле для параметра, и это поле передаётся в метод по ссылке неявным образом. Передача по ссылке означает, что если метод изменяет значение STORE-параметра, то по завершении метода поле получает это новое значение, вычисленное в методе. И при следующем вызове этого метода в этой же строке кода, уже это новое значение будет передано в качестве дополнительного параметра. |
For each method call in a calling class a hidden integer field is created for the stored parameter, and this field is passed to the method by a reference implicitly. Passing by a reference means that if the method changes a STORE-parameter, then after it is finished, new value become the value of the hidden field. And on the next call of the same method in the same line of code, this new value will be passed as an additional parameter. |
| Для того, чтобы "забыть" сохранённые значения параметров, может использоваться вызов метода с модификатором FORGET. При этом будут сброшены в начальное состояние (указанное в модификаторе STORE) значения всех полей, которые создавались для передачи в скрытые параметры методов того же класса, что и метод с модификатором FORGET.
|
To reset stored hidden parameter values it is possible to call a method having a modifier FORGET. Stored parameters created to pass them to methods of the same class as the FORGET method will be set to its initial values (specified in the STORED modifier). |
| Сочетание модификаторов STORE и FORGET позволяет ускорить доступ к массивам данных, индексируемым константными строками. Например, при получении значений полей записей в выборке SELECT из базы данных, или при доступе к колонкам элемента в listview по их заголовкам. Пример реализации доступа к колонкам listview по именам:
|
Modifiers STORE and FORGET together allow speed up accessing data arrays indexing by constant strings. E.g., while obtaining values of fields of records in SELECT results from database, or while accessing items and sub-items of a list view by headers of columns. An example of accessing listview by column names: |
FUN
Cells|_by_constant_names( RESTRICT Name IS CONST: CASE I < 0 ? I = Column_index(Name) ; RESULT = Subitems(Row, I) . |
|
| В данном примере, модификатор FORGET должны иметь все методы, меняющие состав колонок listview и их названия. |
In the above example, the FORGET modifier should be assigned to all the methods changing list view columns set and its names. |
VI. 4. SQL запросы |
VI. 4. SQL queries |
VI. 5. Отменённые и устаревшие классы, записи, перечисления, поля, функции |
VI. 5. Abandoned and deprecated classes, records, enumerations, fields, functions |
| По мере развития классов и библиотек классов, авторы могут приходить к необходимости переименовывать какие-либо вещи, какие-то начинают устаревать, и их поддержка начинает дорого обходиться, какие-то замещаются новыми, какие-то просто прекращают существовать. Чтобы иметь возможность управлять на уровне
языка отмиранием ненужных старых возможностей, и обеспечивать плавный
переход к использованию в новых версиях продукта только новых
возможностей, в язык введены модификаторы
|
While your classes and libraries are developing, you can find it necessary to re-write some things. Some functions, fields and so on becomes too old, supporting it costs more and more, some things are replaced with others etc. To make it possible to control on a language level of a process of a distinction of old entities and provide smooth transition to new features, following modifiers are added to the AL-IV:
|
| Второе применение модификаторов DEPRECATED и ABANDONED - это модификация функциональности в классе-наследнике путем отказа от использования части методов, полей. Или по той причине, что метод требует совершенно иного набора параметра, или его работа существенно отличается от работы аналогичного метода предка. Например, при создании класса {Dialog} как наследника класса {Form}, метод Show декларирован как ABANDONED('Show_modal'). Это сделано для того, чтобы при использовании форм класса {Dialog} программист получал от компилятора сообщение об ошибке при попытке вызова метода Show. К сожалению, сообщение об ошибке от компилятора не будет получено в
том случае, если программист присвоил свою форму класса
{Dialog} переменной класса
{Form}. В этом случае будет вызван отмененный метод (и если он не
содержит код, этот вызов будет проигнорирован). |
VI. 6. Ограничения на значения параметров |
VI. 6. Restrictions to parameter values |
| Функция может иметь
модификаторы
|
A function can have modifiers RESTRICT (unconditional restriction on a parameter) and IF/THEN modifiers (conditional restrictions on parameter values depending on values of other parameters).
|
| Безусловное ограничение имеет
форму:
|
Unconditional restriction has a
form
or (for REAL data type):
or (without specifying certain value):
|
| Условное ограничение имеет
форму:
или
|
A conditional restriction has a form:
or
|
| зачем это может понадобиться?
Например, для реализации набора переходников к библиотеке OpenGL. Можно упростить работу, просто собрав переходники к соответствующим функциям, и передавать так же целочисленные константы, но добавить ограничивающие модификаторы, чтобы обеспечить проверку на недопустимые наборы значений параметров. Это намного проще, чем строить системы классов или использовать для "чистоты" перечисления, и обеспечивает тот же уровень защиты (если не лучший). И при этом работают классические примеры (того же NeHe), практически без изменений (достаточно убрать символы ';' в конце операторов).
В будущем, может использоваться для оптимизации кода: если компилятору известно, что в качестве параметра могут передаваться только небольшое количество констант, то не затруднит для каждого варианта вызова сформировать собственный "экземпляр" функции, оптимизированный путём замены параметра жёстко прописанным значением соответствующей константы. |
When this can be useful ?
E.g., to implement wrappers to the OpenGL library. It is possible to simplify the work just creating simple wrappers to correspondent OpenGL functions and pass just integer constants, but to add restrictions for such parameters to provide checking for only allowed sets of constants. This is much more simple then to create a set of classes or to use enumerated values (since the same values can be used in different functions for different purposes). Restrictions are providing working of classic OpenGL code (e.g. samples from NeHe etc.), almost without any changes (it is sufficient to remove symbols ';' at ends of lines).
This restrictions feature can be used (in future) to optimize code: if the compiler "knows" that only constants can be passed, it can create for each constant a special function version optimized for such constant value. |
VI. 7. Контроль зацикливания |
VI. 7. Infinitive loop control |
|
|
$$STOP!
$$OUT=-