https://xn--80ac3cm.xn--p1ai/api.php?action=feedcontributions&user=%D0%94%D0%B8%D0%B7%D0%B0%D0%B9%D0%BD%D0%B5%D1%80&feedformat=atomТХАБ.РФ - Вклад участника [ru]2024-03-29T15:14:23ZВклад участникаMediaWiki 1.26.4https://xn--80ac3cm.xn--p1ai/index.php?title=%D0%A2%D1%85%D0%B0%D0%B1.%D1%80%D1%84&diff=8455Тхаб.рф2020-11-25T08:51:21Z<p>Дизайнер: </p>
<hr />
<div>'''ТХАБ.РФ''' - вики с семантической разметкой. Концепция проекта пока не устоялась. Есть только самые общие представления.<br />
<br />
== Цель проекта ==<br />
* Создать удобную вики на русском языке, с преимущественно поддержкой отечественных сервисов.<br />
* Тхаб.рф - не является только энциклопедией, т.к. предназначен для для ответа на вопрос не только '''Что''' но и '''Как сделать''', а также хранения всей сопутствующей справочной информации. Т.е. является базой знаний.<br />
<br />
=== Дополнительные цели ===<br />
* По возможности использовать российские/белорусские/украинские интернет сервисы и технологии.<br />
* Изучение возможности создания само окупаемого вебсайта (Хостинг, домен + ~ 3 т.р. мес - администрирование). предоставлении открытой статистики<br />
<br />
=== Граничные условия ===<br />
* Сервис не предназначен для извлечения дохода, но по возможности сервис д.б. самоокупаемым (при больших нагрузках).<br />
<br />
== Особенности проекта ==<br />
* Поддержка SMW<br />
* Возможность встраивать в страницы (карты, видео, [[Карты памяти]] ([[MindMap]])), Диаграммы [[GraphViz]]<br />
* Возможность размещать [[https://тхаб.рф/wiki/ТХАБ:Как_вставить_MagnetURL%3F|MagnetURL]] на страницах. (торренты)<br />
* [[Кириллический домен]]<br />
* Лояльное отношение к Российским/Белорусским/Украинским проектам и разработкам.<br />
* Хостинг в России<br />
<br />
== Технические характеристики ==<br />
* Поддержка HTTPS<br />
* Поддержка SMW<br />
* Хостинг Радиусхост<br />
* Характеристики сервера: Память - 1 Гб, Диск - 15 Гб, 1 ядро процессора - 300 руб/мес или 3000 руб/год (со скидкой)<br />
== Заготовка для SMW карточки ==<br />
Требования пока не устоялись поэтому карточку вики с семантическим шаблоном оформлять не стоит. <br />
<br />
* Название: [[Название:=[[ТХАБ.РФ]]<br />
* Версия Mediawiki: [[Версия Mediawiki:= Mediawiki 1.26.4 )]]<br />
* Операционная система: [[Операционная система:=]] <br />
* PHP: [[PHP:=PHP 5.6.30-0]]<br />
* База Данных: [[База Данных:=10.1.22-MariaDB-1~jessie]]<br />
* HTTP :[[HTTP:=HTTPS]]<br />
* Lua:[[Lua:= нет]]<br />
* Версия SMW :[[Версия SMW:= Semantic MediaWiki 2.4.5]]<br />
* Установленные Расширения :[[Установленные Расширения:=SMW]]<br />
* Сайт:[[Сайт:=https://тхаб.рф/wiki/Служебная:Версия|Версия]]<br />
* Описание :[[Описание:=Открытая вики для инженеров, с семантическими расширениями]]<br />
* Число Статей: [[Число Статей:=1600]]<br />
* Посещаемость:[[Посещаемость:=20-40 чел/сутки]]<br />
* Банерная сеть:[[Банерная сеть:=Нет]]<br />
* Хостинг :[[Хостинг:= ]]<br />
* Поддержка IPv6:[[Поддержка IPv6:=Нет]]<br />
<br />
== См. также ==<br />
* [[Сравнение характеристик различных вики]]<br />
<br />
== Ссылки ==<br />
* [https://Тхаб.рф Сайт ТХАБ.РФ]<br />
<br />
[[Категория:Проекты на движке MediaWiki]]<br />
[[Категория:Вики]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%90%D0%BD%D1%82%D0%B8%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%8B%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%B0&diff=8454Антипростые числа2020-11-25T08:44:09Z<p>Дизайнер: </p>
<hr />
<div>* из простых чисел синтезируются обычные числа<br />
* антипростые числа - наиболее крупные узлы пересечений (коммуникаций)<br />
<br />
<br />
[https://habr.com/ru/post/369741/ Гиктаймс. антипростые числа]<br />
<br />
[[Категория:Математика]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%92%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%BE%D1%80%D0%B0_%D1%82%D0%BE%D0%BA%D0%B0_%D0%BD%D0%B0_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D0%B5%D0%BD%D0%B8%D0%B9&diff=8453Влияние нагрузки трансформатора тока на точность измерений2020-11-25T08:39:24Z<p>Дизайнер: </p>
<hr />
<div>Выжимка обсуждения с ветки форума АСУ ТП<br />
<br />
Хотелось бы знать влияния нагрузки (включение во вторичную цепь трансформатора тока последовательно еще одного амперметра) на точность их показаний?<br />
----<br />
* [[Трансформатор тока]] вики статья<br />
----<br />
* Практически не влияет. Слишком большой коэффициент трансформации<br />
* вообще никак (если, конечно, это не последняя капля до перегруза вторички)<br />
* можно почитать [[МИ 3022-2006 "Нормализация нагрузки вторичных цепей измерительных ТТ"]] там всё есть<br />
* Элементарно. У трансформатора тока есть [[номинальная мощность]], в [[вольтампер]]ах (ВА), она на нём указана, на бирке. Каждый прибор, включенный во вторичной обмотке, потребляет свою мощность по токовой цепи - это каталожные данные. Просто суммируйте потребляемую мощность всех приборов (по каждой фазе отдельно) и если она не превысит номинальную мощность ТТ - ТТ останется в [[классе точности]]. Амперметр кушает как правило от 0,5 до 3 ВА (зависит от типа). ТТ номинала 50/5, как правило, маломощные, так что проверяйте, считайте.<br />
----<br />
А ведь режим работы трансформатора тока К. З.!! И он очень не любит разомкнутую вторичную обмотку!?<br />
* Трансформатору всё равно - а вот электроустановке не понравится, потому что на разомкнутой обмотке образуется напряжение, стремящееся к бесконечности - прошьёт установку, и сам трансформатор может перекрыть разрядом по обмотке, и персонал рискует поймать эти киловольты на себя.<br />
<br />
== Ссылки ==<br />
* [http://asutpforum.ru/viewtopic.php?f=105&t=8333 обсуждение]<br />
<br />
[[Категория:АСУ ТП]]<br />
[[Категория:Как сделать]]<br />
<br />
{{i}}</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%9A%D0%B0%D0%BA_%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C_%D1%81%D0%B2%D0%BE%D0%B9_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82&diff=8416Перфолента.NET. ООП. Как написать свой атрибут2020-11-12T13:50:21Z<p>Дизайнер: /* Написание собственного атрибута и его использование */</p>
<hr />
<div>== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем // Процедуре Страт присвоен атрибут ВидноВсем <br />
// и атрибут АнглийскийСиноним значение которого равно "Start"<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать программу содержащую процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8415Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T13:36:29Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы (модулям, полям, функциям) дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько значений, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Фактически '''Атрибут - это метка''' которую можно прикрепить к полю, функции, методу, самой программе (сборке) или модулю программы (DLL) значение которой сможет прочитать другой компонент этой или другой программы:<br />
<br />
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программе содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "ЗачениеАтрибута" которое сможет использовать по своему усмотрению.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8414Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T13:36:03Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы (модулям, полям, функциям) дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько значений, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Фактически Атрибут - это метка которую можно прикрепить к полю, функции, методу, самой программе (сборке) или модулю программы (DLL) значение которой сможет прочитать другой компонент этой или другой программы:<br />
<br />
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программе содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "ЗачениеАтрибута" которое сможет использовать по своему усмотрению.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%9A%D0%B0%D0%BA_%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C_%D1%81%D0%B2%D0%BE%D0%B9_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82&diff=8413Перфолента.NET. ООП. Как написать свой атрибут2020-11-12T13:31:05Z<p>Дизайнер: </p>
<hr />
<div>== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_Net_Farmework&diff=8412Перфолента.NET. ООП. Атрибуты Net Farmework2020-11-12T13:30:52Z<p>Дизайнер: </p>
<hr />
<div>== Атрибуты NET Framework и их использование ==<br />
<br />
Операторы '''АтрибутСборки''' и '''АтрибутМодуля''' предназначены не только для установки атрибутов определенных в Net. Можно и свои атрибуты назначать для сборки и модуля. В Net определены несколько атрибутов, которые к сборке и модулю более-менее часто применяются, а свои атрибуты редко к сборке применяются, но можно это делать, если придумаете полезное применение.<br />
<br />
В Net можно найти атрибуты для любых элементов программы, и для классов и для свойств, методов, полей, параметров методов и т.д.<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
'''АтрибутСборки''' System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
'''АтрибутМодуля''' System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8411Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T13:30:30Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы (модулям, полям, функциям) дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько значений, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программе содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "ЗачениеАтрибута" которое сможет использовать по своему усмотрению.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/Article.asp?code=20201106234710055491 Первоисточник<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_Net_Farmework&diff=8410Перфолента.NET. ООП. Атрибуты Net Farmework2020-11-12T13:28:56Z<p>Дизайнер: /* Атрибуты NET Framework и их использование */</p>
<hr />
<div>== Атрибуты NET Framework и их использование ==<br />
<br />
Операторы '''АтрибутСборки''' и '''АтрибутМодуля''' предназначены не только для установки атрибутов определенных в Net. Можно и свои атрибуты назначать для сборки и модуля. В Net определены несколько атрибутов, которые к сборке и модулю более-менее часто применяются, а свои атрибуты редко к сборке применяются, но можно это делать, если придумаете полезное применение.<br />
<br />
В Net можно найти атрибуты для любых элементов программы, и для классов и для свойств, методов, полей, параметров методов и т.д.<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
'''АтрибутСборки''' System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
'''АтрибутМодуля''' System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_Net_Farmework&diff=8409Перфолента.NET. ООП. Атрибуты Net Farmework2020-11-12T13:28:28Z<p>Дизайнер: /* Атрибуты NET Framework и их использование */</p>
<hr />
<div>== Атрибуты NET Framework и их использование ==<br />
<br />
Операторы АтрибутСборки и АтрибутМодуля предназначены не только для установки атрибутов определенных в Net. Можно и свои атрибуты назначать для сборки и модуля. В Net определены несколько атрибутов, которые к сборке и модулю более-менее часто применяются, а свои атрибуты редко к сборке применяются, но можно это делать, если придумаете полезное применение.<br />
<br />
В Net можно найти атрибуты для любых элементов программы, и для классов и для свойств, методов, полей, параметров методов и т.д.<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
'''АтрибутСборки''' System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
'''АтрибутМодуля''' System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8408Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T13:22:33Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы (модулям, полям, функциям) дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько значений, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программе содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "ЗачениеАтрибута" которое сможет использовать по своему усмотрению.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8407Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T13:15:18Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Значение присвоенное атрибуту '''ИмяАтрибута''' процедуры '''ИмяПроцедуры''' сможет прочитать любая программа, которая обратится к программы содержащей процедуру '''ИмяПроцедуры''' т.е. внешняя программа прочитав значение атрибута ИмяАтрибута у процедуры ИмяПроцедуры получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%9A%D0%B0%D0%BA_%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C_%D1%81%D0%B2%D0%BE%D0%B9_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82&diff=8406Перфолента.NET. ООП. Как написать свой атрибут2020-11-12T12:22:02Z<p>Дизайнер: </p>
<hr />
<div>== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5_%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8405Объектно-ориентированное программирование на языке Перфолента.NET2020-11-12T12:20:52Z<p>Дизайнер: /* Копия официального описания ООП на Перфолента.NET (можно править и дополнять) */</p>
<hr />
<div><br />
== Копия официального описания ООП на Перфолента.NET (можно править и дополнять) ==<br />
* [[Перфолента.NET. ООП. Терминология: классы, объекты и типы в языке Перфолента]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Поля]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Конструкторы]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]<br />
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
** [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
** [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Упрощенное описание ООП (Не править в процессе написания)==<br />
Для понимания темы Вам необходимо понимать что такое Функция и Процедура. Как их использовать.<br />
* см. [[Объектно Ориентированное-Программирование простое описание]]<br />
<br />
== Используемые, но не введённые понятия (временный раздел для редактирования) ==<br />
* Интерфейс<br />
* Конструктор (из примера кода)<br />
* Наследование<br />
* Структура<br />
* Поле - переменная Объекта<br />
Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями... <br />
* [[Атрибут]] Поля - свойство переменной<br />
** &ВидноВсем - к переменной могут обращаться другие объекты<br />
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)<br />
<br />
=== Перечисления ===<br />
<br />
* [[Перечисления]] - Перечислимый тип данных, т.е. переменные этого типа данных - могут принимать всего несколько значений которые перечислены при объявления типа.<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова '''Поле''' и по умолчанию имеют атрибут '''ВидноВсем'''. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
== Определения Класса и связанных понятий ==<br />
<br />
'''Важно''': <br />
* Классы объявляются после конца программы (после оператора '''КонецПрограммы''').<br />
* Функции и процедуры объявляются в самом конце программы между операторами '''КонецПроцедуры''' (Старт) и '''КонецПрограммы'''.<br />
<br />
'''Класс''' - это составной тип, который, для удобства программиста, логические объединяет вместе переменный, процедуры и функции которые эти переменные используют. Аналогом класса в процедурном программировании является ТИП переменной.<br />
<br />
Класс состоит из:<br />
* Переменные - чтобы отличать их от обычных переменных в классах они называются '''Поля''' или '''Свойства''' (объекта).<br />
* Функции и Процедуры использующие эти переменные - чтобы отличать их от обычных функций и процедур в классах они называются '''Методы''' и '''События''' (функции которые реагируют на внешние по отношению к объекту события, например пользователь Щёлкает по кнопке "Закрыть окно")<br />
<br />
'''Объект''' - это один экземпляр класса, т.е. Класс это "штамп" из заготовок переменных и привязанных к ним процедур которые работают с этими переменными.<br />
<br />
Чем отличается Переменная от Поля ? <br />
* Переменная - используется при вычислениях внутри Функции или Процедуры. Как только процедура или функция завершила свою работу и передала результат работы в то место программы откуда её вызвали, то все используемые ей переменные уничтожаются, чтобы не занимать память.<br />
* Поле - это "переменная" используемая внутри объектов. Сточки зрения компилятора она организованна совсем по другому. В Поле одного объекта может писать или читать другой объект (если ему разрешать читать или писать в поле принадлежащее другому объекту). Поле гораздо более мощная конструкция, при создании поля программист может не только указать Тип хранящегося в нём значения, но и разрешить или запретить другим методом других объектов читать содержащееся в этом Поле значения.<br />
<br />
А если при использования '''Поля''' другой объект попытается записать в '''Поле''' "переменную правильного типа, но неправильного значения" или у объекта необходимо изменять несколько '''Полей''' синхронно или по определённому алгоритму ?<br />
<br />
Для этого к выбранному '''Полю''' можно добавить 2 специальных метода со стандартными именами '''Прочитать''' и '''Установить'''. При попытке прочитать значение этого поля или записать в него какое либо значение автоматически будут вырываться соответствующие методы '''Прочитать''' и '''Установить''' - внутри которых будут прописаны соответствующие алгоритмы по проверке значения присваиваемых переменных и/или синхронному изменению значений нескольких Полей этого объекта. Чтобы отличить такое "Поле" от обычных его называют - '''Свойство'''.<br />
<br />
'''Конструктор Класса''' - это просто специальная процедура которая присваивает значения одному или нескольким Полям объекта при его создании по прописанным в неё алгоритмам.<br />
<br />
<br />
=== Дополнительно ===<br />
* '''Атрибуты Поля''' (свойства Переменной Класса) - Переменные кроме своего значения и свойства ТИП, имеют ещё (Свойство) '''&ВидноВсем'''. Чтобы отличать свойства объекта и свойства переменных, свойства переменных называются Атрибуты.<br />
** '''&ВидноВсем''' - без этого Атрибута Поля (переменной) поле было бы видно только тем методам (функциям и процедурам), которые расположены внутри класса. - Т.е. Атрибут ВидоВсем делает из Поля (Переменной) '''Интерфейс''' ?<br />
<br />
== Объявление и создание Класса ==<br />
Рассмотрим определение простейшего класса:<br />
<br />
Класс Животное<br />
//тут можно определить свойства и методы работы с классом<br />
КонецКласса<br />
<br />
Мы можем создавать экземпляры объектов класса Животное оператором '''Новый'''. И несмотря на то, что у этого объекта нет ни каких свойств и методов, ему можно придумать полезное применение. Например, он может быть родителем классов Кошка и Собака.<br />
<br />
'''На заметку:''' Если для класса не указан родитель, то его родителем является класс Объект, который является корневым родителем всей иерархии классов, используемых в .Net.<br />
<br />
=== Добавляем в Класс Переменные - Поля ===<br />
<br />
В языке Перфолента любая информация класса хранится в '''Полях'''.<br />
<br />
'''Поле''' — это переменная, в которой хранится один элемент данных конкретного объекта (экземпляра класса) указанного класса или элемент данных общий для класса.<br />
<br />
Класс Собака<br />
// общее для всех экземпляров класса Поле (переменная) <br />
Объект "Собака1"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Жучка"<br />
Объект "Собака2"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Лайка"<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
Иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
==== '''не проверенное''' ====<br />
<br />
Для программистов: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared (разделяемый между несколькими), т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь ''атрибут'' '''ОбщийДляКласса'''.<br />
<br />
Добавим в наш класс поле Имя:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
КонецКласса<br />
<br />
Теперь мы можем дать собакам имена, например, так:<br />
<br />
Собака1 = '''Новый''' Собака<br />
Собака1.Имя = "Жучка" <br />
Собака2 = '''Новый''' Собака<br />
Собака2.Имя = "Лайка" <br />
<br />
Обратите внимание на ''атрибут поля'' '''ВидноВсем''', без него поле было бы видно только тем методам, которые расположены ''внутри класса''. Подробнее атрибуты видимости членов мы рассмотрим позднее.<br />
<br />
Добавим в класс ещё полей:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
КонецКласса<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
<br />
Теперь наш класс может содержать достаточно информации, что бы можно было создавать объекты, соответствующие конкретным собакам. Однако, иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
Класс Собака Родитель Животное<br />
//поля общие для класса<br />
&ВидноВсем, ОбщийДляКласса Поле КоличествоЭкземпляров тип Целое<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщийВес тип Целое<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам (функциям) описанным внутри класса<br />
&ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата<br />
//-----------------------------------------------<br />
//поля для каждого экземпляра созданных объектов<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам описанным внутри класса<br />
Поле ВремяСозданияОбъекта тип Дата<br />
КонецКласса<br />
<br />
Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.<br />
<br />
=== Задание первоначальных значений переменных (Полей) при создании Объекта (Инициализация полей) ===<br />
<br />
При создании объекта (экземпляра класса) его Поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.<br />
<br />
Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:<br />
<br />
Поле ВремяСозданияОбъекта тип Дата = ТекущаяДата<br />
<br />
Точно так же могут инициализироваться и общие для класса поля, однако тут есть один нюанс. Поле общее для класса буде инициализировано один раз при первом обращении к любому члену этого класса. При создании экземпляра объекта значение общего для класса поля может быть прочитано и/или изменено, например, счетчик создаваемых объектов может быть увеличен на единицу.<br />
<br />
===Поля в интерфейсах.===<br />
<br />
Так как интерфейсы не содержат данных, в них не допустимо определение полей.<br />
<br />
===Поля в структурах.===<br />
<br />
Поля в структурах полностью аналогичны по правилам создания и использования полям классов, описанным выше, за исключением одного нюанса:<br />
инициализация полей структур допустима только для полей общих для класса.<br />
<br />
Структура МояСтруктура<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщееПоле тип Целое = 111 // Правильно. Инициализация допустима.<br />
&ВидноВсем Поле ПриватноеПоле1 тип Целое // Правильно. Нет инициализации.<br />
&ВидноВсем Поле ПриватноеПоле2 тип Целое = 222 // ОШИБКА !!! Инициализация НЕ допустима.<br />
КонецСтруктуры<br />
<br />
===Поля в модулях.===<br />
<br />
Как мы уже знаем, Модуль — это специализированная версия класса, экземпляры объектов которого создавать нельзя, а все члены являются общими для класса.<br />
<br />
Поэтому полям, объявленным в модулях (в том числе в модуле Программа), нет необходимости задавать атрибут ОбщийДляКласса, они и так уже общие.<br />
<br />
Программа МояПрограмма<br />
Поле ВремяСтартаПрограммы тип Дата = ТекущаяДата<br />
КонецПрограммы<br />
<br />
Модуль ОбщиеДанные<br />
&ВидноВсем Поле ОбщаяСтоимость тип Число = 0<br />
КонецМодуля<br />
<br />
=== Поля в перечислениях ===<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова Поле и по умолчанию имеют атрибут ВидноВсем. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
=== Множественное определение полей одного типа.===<br />
<br />
Как и в случае с переменными, несколько полей одного типа можно определить одной строкой кода:<br />
<br />
&ВидноВсем Поле Вес, Рост, ШиринаПлеч, РазмерОбуви, РазмерШапки тип Число = 0<br />
<br />
Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько переменных инициализируется, например:<br />
<br />
Поле Счетчик тип Целое = 0<br />
Поле Один, Два, Три, Четыре, Пять тип Целое = ++Счетчик<br />
// и где-то в методе<br />
ВыводСтроки ""+Один+Два+Три+Четыре+Пять<br />
<br />
На экран консоли будет выведено: 12345.<br />
<br />
<br />
'''Вывод:''' Поле – это единственное средство для хранения данных объекта находящегося в памяти компьютера. Поле обязательно имеет Тип и может быть либо общим для класса, создающимся в одном экземпляре, либо объектным, создающимся в каждом экземпляре объекта. В разных видах элементов программы поля имеют особенности написания и использования во время компиляции и выполнения программы.<br />
<br />
== Наследование (надо ввести понятие ниже)==<br />
Создадим классы Кошка и Собака, указав, что родителем для них является Класс Животное:<br />
<br />
'''Класс''' Кошка '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
'''Класс''' Собака '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
Теперь покажем, как можно эти классы использовать:<br />
<br />
МойКот = '''Новый''' Кот // создадим объект МойКот сложного типа - Кот<br />
ПриветЖивотное(МойКот) // передадим объект МойКот <br />
<br />
МояСобака = '''Новый''' Собака<br />
ПриветЖивотное(МояСобака)<br />
<br />
//где-то ниже определим процедуру<br />
'''Процедура''' ПриветЖивотное(МоёЖивотное '''тип''' Животное) // процедура принимает объект типа Животное<br />
'''Выбор Для''' МоёЖивотное // оператор выбора Выбор Для<br />
'''Когда''' ЭтоТип Кот<br />
'''ВыводСтроки''' "Привет кот!"<br />
'''Когда''' '''ЭтоТип''' Собака<br />
'''ВыводСтроки''' "Привет собака!"<br />
'''Иначе'''<br />
'''ВыводСтроки''' "Привет не известное животное!"<br />
'''КонецВыбора'''<br />
'''КонецПроцедуры'''<br />
<br />
Как видно из этого примера, процедура ПриветЖивотное() может приветствовать животное любого типа, даже такого, который на момент написания программы еще не существовал. Главное, чтобы не известное животное было потомком класса Животное. А вот классы Кот и Собака этой процедуре известны и приветствие выводится вполне конкретное.<br />
<br />
Таким образом, мы извлекли пользу от использования классов не имеющих ни каких свойств и методов (кроме методов родительского типа Объект). Нам пригодилась сама иерархия, согласно которой мы классифицировали объекты.<br />
<br />
Умнику на заметку: Отметьте для себя связь терминов Класс и Классификация. Вы должны выстраивать иерархию классов не как попало, а по определенным критериям, что бы можно было сказать, что вы их классифицировали.<br />
<br />
== Ссылки ==<br />
* [http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language ПРОМОКОД - официальная страница языка программирования Перфолента.NET]<br />
* [http://promcod.com.ua/Article.asp?code=20200902191745030929 ООП на Перфолента.NET часть 1. Терминология: классы, объекты и типы в языке Перфолента]<br />
* [http://promcod.com.ua/Article.asp?code=20200909140544010807 ООП на Перфолента.NET часть 2. Конструируем класс. Поля]<br />
[[Категория:Описание языка Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5_%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8404Объектно-ориентированное программирование на языке Перфолента.NET2020-11-12T12:20:35Z<p>Дизайнер: /* Копия официального описания ООП на Перфолента.NET (можно править и дополнять) */</p>
<hr />
<div><br />
== Копия официального описания ООП на Перфолента.NET (можно править и дополнять) ==<br />
* [[Перфолента.NET. ООП. Терминология: классы, объекты и типы в языке Перфолента]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Поля]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Конструкторы]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]<br />
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
** [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
** [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
<br />
== Упрощенное описание ООП (Не править в процессе написания)==<br />
Для понимания темы Вам необходимо понимать что такое Функция и Процедура. Как их использовать.<br />
* см. [[Объектно Ориентированное-Программирование простое описание]]<br />
<br />
== Используемые, но не введённые понятия (временный раздел для редактирования) ==<br />
* Интерфейс<br />
* Конструктор (из примера кода)<br />
* Наследование<br />
* Структура<br />
* Поле - переменная Объекта<br />
Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями... <br />
* [[Атрибут]] Поля - свойство переменной<br />
** &ВидноВсем - к переменной могут обращаться другие объекты<br />
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)<br />
<br />
=== Перечисления ===<br />
<br />
* [[Перечисления]] - Перечислимый тип данных, т.е. переменные этого типа данных - могут принимать всего несколько значений которые перечислены при объявления типа.<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова '''Поле''' и по умолчанию имеют атрибут '''ВидноВсем'''. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
== Определения Класса и связанных понятий ==<br />
<br />
'''Важно''': <br />
* Классы объявляются после конца программы (после оператора '''КонецПрограммы''').<br />
* Функции и процедуры объявляются в самом конце программы между операторами '''КонецПроцедуры''' (Старт) и '''КонецПрограммы'''.<br />
<br />
'''Класс''' - это составной тип, который, для удобства программиста, логические объединяет вместе переменный, процедуры и функции которые эти переменные используют. Аналогом класса в процедурном программировании является ТИП переменной.<br />
<br />
Класс состоит из:<br />
* Переменные - чтобы отличать их от обычных переменных в классах они называются '''Поля''' или '''Свойства''' (объекта).<br />
* Функции и Процедуры использующие эти переменные - чтобы отличать их от обычных функций и процедур в классах они называются '''Методы''' и '''События''' (функции которые реагируют на внешние по отношению к объекту события, например пользователь Щёлкает по кнопке "Закрыть окно")<br />
<br />
'''Объект''' - это один экземпляр класса, т.е. Класс это "штамп" из заготовок переменных и привязанных к ним процедур которые работают с этими переменными.<br />
<br />
Чем отличается Переменная от Поля ? <br />
* Переменная - используется при вычислениях внутри Функции или Процедуры. Как только процедура или функция завершила свою работу и передала результат работы в то место программы откуда её вызвали, то все используемые ей переменные уничтожаются, чтобы не занимать память.<br />
* Поле - это "переменная" используемая внутри объектов. Сточки зрения компилятора она организованна совсем по другому. В Поле одного объекта может писать или читать другой объект (если ему разрешать читать или писать в поле принадлежащее другому объекту). Поле гораздо более мощная конструкция, при создании поля программист может не только указать Тип хранящегося в нём значения, но и разрешить или запретить другим методом других объектов читать содержащееся в этом Поле значения.<br />
<br />
А если при использования '''Поля''' другой объект попытается записать в '''Поле''' "переменную правильного типа, но неправильного значения" или у объекта необходимо изменять несколько '''Полей''' синхронно или по определённому алгоритму ?<br />
<br />
Для этого к выбранному '''Полю''' можно добавить 2 специальных метода со стандартными именами '''Прочитать''' и '''Установить'''. При попытке прочитать значение этого поля или записать в него какое либо значение автоматически будут вырываться соответствующие методы '''Прочитать''' и '''Установить''' - внутри которых будут прописаны соответствующие алгоритмы по проверке значения присваиваемых переменных и/или синхронному изменению значений нескольких Полей этого объекта. Чтобы отличить такое "Поле" от обычных его называют - '''Свойство'''.<br />
<br />
'''Конструктор Класса''' - это просто специальная процедура которая присваивает значения одному или нескольким Полям объекта при его создании по прописанным в неё алгоритмам.<br />
<br />
<br />
=== Дополнительно ===<br />
* '''Атрибуты Поля''' (свойства Переменной Класса) - Переменные кроме своего значения и свойства ТИП, имеют ещё (Свойство) '''&ВидноВсем'''. Чтобы отличать свойства объекта и свойства переменных, свойства переменных называются Атрибуты.<br />
** '''&ВидноВсем''' - без этого Атрибута Поля (переменной) поле было бы видно только тем методам (функциям и процедурам), которые расположены внутри класса. - Т.е. Атрибут ВидоВсем делает из Поля (Переменной) '''Интерфейс''' ?<br />
<br />
== Объявление и создание Класса ==<br />
Рассмотрим определение простейшего класса:<br />
<br />
Класс Животное<br />
//тут можно определить свойства и методы работы с классом<br />
КонецКласса<br />
<br />
Мы можем создавать экземпляры объектов класса Животное оператором '''Новый'''. И несмотря на то, что у этого объекта нет ни каких свойств и методов, ему можно придумать полезное применение. Например, он может быть родителем классов Кошка и Собака.<br />
<br />
'''На заметку:''' Если для класса не указан родитель, то его родителем является класс Объект, который является корневым родителем всей иерархии классов, используемых в .Net.<br />
<br />
=== Добавляем в Класс Переменные - Поля ===<br />
<br />
В языке Перфолента любая информация класса хранится в '''Полях'''.<br />
<br />
'''Поле''' — это переменная, в которой хранится один элемент данных конкретного объекта (экземпляра класса) указанного класса или элемент данных общий для класса.<br />
<br />
Класс Собака<br />
// общее для всех экземпляров класса Поле (переменная) <br />
Объект "Собака1"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Жучка"<br />
Объект "Собака2"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Лайка"<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
Иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
==== '''не проверенное''' ====<br />
<br />
Для программистов: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared (разделяемый между несколькими), т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь ''атрибут'' '''ОбщийДляКласса'''.<br />
<br />
Добавим в наш класс поле Имя:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
КонецКласса<br />
<br />
Теперь мы можем дать собакам имена, например, так:<br />
<br />
Собака1 = '''Новый''' Собака<br />
Собака1.Имя = "Жучка" <br />
Собака2 = '''Новый''' Собака<br />
Собака2.Имя = "Лайка" <br />
<br />
Обратите внимание на ''атрибут поля'' '''ВидноВсем''', без него поле было бы видно только тем методам, которые расположены ''внутри класса''. Подробнее атрибуты видимости членов мы рассмотрим позднее.<br />
<br />
Добавим в класс ещё полей:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
КонецКласса<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
<br />
Теперь наш класс может содержать достаточно информации, что бы можно было создавать объекты, соответствующие конкретным собакам. Однако, иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
Класс Собака Родитель Животное<br />
//поля общие для класса<br />
&ВидноВсем, ОбщийДляКласса Поле КоличествоЭкземпляров тип Целое<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщийВес тип Целое<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам (функциям) описанным внутри класса<br />
&ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата<br />
//-----------------------------------------------<br />
//поля для каждого экземпляра созданных объектов<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам описанным внутри класса<br />
Поле ВремяСозданияОбъекта тип Дата<br />
КонецКласса<br />
<br />
Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.<br />
<br />
=== Задание первоначальных значений переменных (Полей) при создании Объекта (Инициализация полей) ===<br />
<br />
При создании объекта (экземпляра класса) его Поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.<br />
<br />
Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:<br />
<br />
Поле ВремяСозданияОбъекта тип Дата = ТекущаяДата<br />
<br />
Точно так же могут инициализироваться и общие для класса поля, однако тут есть один нюанс. Поле общее для класса буде инициализировано один раз при первом обращении к любому члену этого класса. При создании экземпляра объекта значение общего для класса поля может быть прочитано и/или изменено, например, счетчик создаваемых объектов может быть увеличен на единицу.<br />
<br />
===Поля в интерфейсах.===<br />
<br />
Так как интерфейсы не содержат данных, в них не допустимо определение полей.<br />
<br />
===Поля в структурах.===<br />
<br />
Поля в структурах полностью аналогичны по правилам создания и использования полям классов, описанным выше, за исключением одного нюанса:<br />
инициализация полей структур допустима только для полей общих для класса.<br />
<br />
Структура МояСтруктура<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщееПоле тип Целое = 111 // Правильно. Инициализация допустима.<br />
&ВидноВсем Поле ПриватноеПоле1 тип Целое // Правильно. Нет инициализации.<br />
&ВидноВсем Поле ПриватноеПоле2 тип Целое = 222 // ОШИБКА !!! Инициализация НЕ допустима.<br />
КонецСтруктуры<br />
<br />
===Поля в модулях.===<br />
<br />
Как мы уже знаем, Модуль — это специализированная версия класса, экземпляры объектов которого создавать нельзя, а все члены являются общими для класса.<br />
<br />
Поэтому полям, объявленным в модулях (в том числе в модуле Программа), нет необходимости задавать атрибут ОбщийДляКласса, они и так уже общие.<br />
<br />
Программа МояПрограмма<br />
Поле ВремяСтартаПрограммы тип Дата = ТекущаяДата<br />
КонецПрограммы<br />
<br />
Модуль ОбщиеДанные<br />
&ВидноВсем Поле ОбщаяСтоимость тип Число = 0<br />
КонецМодуля<br />
<br />
=== Поля в перечислениях ===<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова Поле и по умолчанию имеют атрибут ВидноВсем. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
=== Множественное определение полей одного типа.===<br />
<br />
Как и в случае с переменными, несколько полей одного типа можно определить одной строкой кода:<br />
<br />
&ВидноВсем Поле Вес, Рост, ШиринаПлеч, РазмерОбуви, РазмерШапки тип Число = 0<br />
<br />
Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько переменных инициализируется, например:<br />
<br />
Поле Счетчик тип Целое = 0<br />
Поле Один, Два, Три, Четыре, Пять тип Целое = ++Счетчик<br />
// и где-то в методе<br />
ВыводСтроки ""+Один+Два+Три+Четыре+Пять<br />
<br />
На экран консоли будет выведено: 12345.<br />
<br />
<br />
'''Вывод:''' Поле – это единственное средство для хранения данных объекта находящегося в памяти компьютера. Поле обязательно имеет Тип и может быть либо общим для класса, создающимся в одном экземпляре, либо объектным, создающимся в каждом экземпляре объекта. В разных видах элементов программы поля имеют особенности написания и использования во время компиляции и выполнения программы.<br />
<br />
== Наследование (надо ввести понятие ниже)==<br />
Создадим классы Кошка и Собака, указав, что родителем для них является Класс Животное:<br />
<br />
'''Класс''' Кошка '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
'''Класс''' Собака '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
Теперь покажем, как можно эти классы использовать:<br />
<br />
МойКот = '''Новый''' Кот // создадим объект МойКот сложного типа - Кот<br />
ПриветЖивотное(МойКот) // передадим объект МойКот <br />
<br />
МояСобака = '''Новый''' Собака<br />
ПриветЖивотное(МояСобака)<br />
<br />
//где-то ниже определим процедуру<br />
'''Процедура''' ПриветЖивотное(МоёЖивотное '''тип''' Животное) // процедура принимает объект типа Животное<br />
'''Выбор Для''' МоёЖивотное // оператор выбора Выбор Для<br />
'''Когда''' ЭтоТип Кот<br />
'''ВыводСтроки''' "Привет кот!"<br />
'''Когда''' '''ЭтоТип''' Собака<br />
'''ВыводСтроки''' "Привет собака!"<br />
'''Иначе'''<br />
'''ВыводСтроки''' "Привет не известное животное!"<br />
'''КонецВыбора'''<br />
'''КонецПроцедуры'''<br />
<br />
Как видно из этого примера, процедура ПриветЖивотное() может приветствовать животное любого типа, даже такого, который на момент написания программы еще не существовал. Главное, чтобы не известное животное было потомком класса Животное. А вот классы Кот и Собака этой процедуре известны и приветствие выводится вполне конкретное.<br />
<br />
Таким образом, мы извлекли пользу от использования классов не имеющих ни каких свойств и методов (кроме методов родительского типа Объект). Нам пригодилась сама иерархия, согласно которой мы классифицировали объекты.<br />
<br />
Умнику на заметку: Отметьте для себя связь терминов Класс и Классификация. Вы должны выстраивать иерархию классов не как попало, а по определенным критериям, что бы можно было сказать, что вы их классифицировали.<br />
<br />
== Ссылки ==<br />
* [http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language ПРОМОКОД - официальная страница языка программирования Перфолента.NET]<br />
* [http://promcod.com.ua/Article.asp?code=20200902191745030929 ООП на Перфолента.NET часть 1. Терминология: классы, объекты и типы в языке Перфолента]<br />
* [http://promcod.com.ua/Article.asp?code=20200909140544010807 ООП на Перфолента.NET часть 2. Конструируем класс. Поля]<br />
[[Категория:Описание языка Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%9A%D0%B0%D0%BA_%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D1%82%D1%8C_%D1%81%D0%B2%D0%BE%D0%B9_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82&diff=8403Перфолента.NET. ООП. Как написать свой атрибут2020-11-12T12:19:46Z<p>Дизайнер: Новая страница: «== Устройство атрибута == Технически, атрибуты — это специальные классы, унаследованные…»</p>
<hr />
<div>== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8402Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:19:35Z<p>Дизайнер: /* Написание собственного атрибута и его использование */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_Net_Farmework&diff=8401Перфолента.NET. ООП. Атрибуты Net Farmework2020-11-12T12:18:42Z<p>Дизайнер: Новая страница: «== Атрибуты NET Framework и их использование == === Атрибуты сборки (.NET) === В .Net определены разнооб…»</p>
<hr />
<div>== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8400Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:18:04Z<p>Дизайнер: /* Атрибуты NET Framework и их использование */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8399Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:17:20Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== См. также ==<br />
* [[Перфолента.NET. ООП. Атрибуты Net Farmework]]<br />
* [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5_%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8398Объектно-ориентированное программирование на языке Перфолента.NET2020-11-12T12:15:40Z<p>Дизайнер: /* Копия официального описания ООП на Перфолента.NET (можно править и дополнять) */</p>
<hr />
<div><br />
== Копия официального описания ООП на Перфолента.NET (можно править и дополнять) ==<br />
* [[Перфолента.NET. ООП. Терминология: классы, объекты и типы в языке Перфолента]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Поля]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Конструкторы]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]<br />
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
** [[Перфолента.NET. ООП. Как написать свой атрибут]]<br />
<br />
== Упрощенное описание ООП (Не править в процессе написания)==<br />
Для понимания темы Вам необходимо понимать что такое Функция и Процедура. Как их использовать.<br />
* см. [[Объектно Ориентированное-Программирование простое описание]]<br />
<br />
== Используемые, но не введённые понятия (временный раздел для редактирования) ==<br />
* Интерфейс<br />
* Конструктор (из примера кода)<br />
* Наследование<br />
* Структура<br />
* Поле - переменная Объекта<br />
Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями... <br />
* [[Атрибут]] Поля - свойство переменной<br />
** &ВидноВсем - к переменной могут обращаться другие объекты<br />
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)<br />
<br />
=== Перечисления ===<br />
<br />
* [[Перечисления]] - Перечислимый тип данных, т.е. переменные этого типа данных - могут принимать всего несколько значений которые перечислены при объявления типа.<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова '''Поле''' и по умолчанию имеют атрибут '''ВидноВсем'''. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
== Определения Класса и связанных понятий ==<br />
<br />
'''Важно''': <br />
* Классы объявляются после конца программы (после оператора '''КонецПрограммы''').<br />
* Функции и процедуры объявляются в самом конце программы между операторами '''КонецПроцедуры''' (Старт) и '''КонецПрограммы'''.<br />
<br />
'''Класс''' - это составной тип, который, для удобства программиста, логические объединяет вместе переменный, процедуры и функции которые эти переменные используют. Аналогом класса в процедурном программировании является ТИП переменной.<br />
<br />
Класс состоит из:<br />
* Переменные - чтобы отличать их от обычных переменных в классах они называются '''Поля''' или '''Свойства''' (объекта).<br />
* Функции и Процедуры использующие эти переменные - чтобы отличать их от обычных функций и процедур в классах они называются '''Методы''' и '''События''' (функции которые реагируют на внешние по отношению к объекту события, например пользователь Щёлкает по кнопке "Закрыть окно")<br />
<br />
'''Объект''' - это один экземпляр класса, т.е. Класс это "штамп" из заготовок переменных и привязанных к ним процедур которые работают с этими переменными.<br />
<br />
Чем отличается Переменная от Поля ? <br />
* Переменная - используется при вычислениях внутри Функции или Процедуры. Как только процедура или функция завершила свою работу и передала результат работы в то место программы откуда её вызвали, то все используемые ей переменные уничтожаются, чтобы не занимать память.<br />
* Поле - это "переменная" используемая внутри объектов. Сточки зрения компилятора она организованна совсем по другому. В Поле одного объекта может писать или читать другой объект (если ему разрешать читать или писать в поле принадлежащее другому объекту). Поле гораздо более мощная конструкция, при создании поля программист может не только указать Тип хранящегося в нём значения, но и разрешить или запретить другим методом других объектов читать содержащееся в этом Поле значения.<br />
<br />
А если при использования '''Поля''' другой объект попытается записать в '''Поле''' "переменную правильного типа, но неправильного значения" или у объекта необходимо изменять несколько '''Полей''' синхронно или по определённому алгоритму ?<br />
<br />
Для этого к выбранному '''Полю''' можно добавить 2 специальных метода со стандартными именами '''Прочитать''' и '''Установить'''. При попытке прочитать значение этого поля или записать в него какое либо значение автоматически будут вырываться соответствующие методы '''Прочитать''' и '''Установить''' - внутри которых будут прописаны соответствующие алгоритмы по проверке значения присваиваемых переменных и/или синхронному изменению значений нескольких Полей этого объекта. Чтобы отличить такое "Поле" от обычных его называют - '''Свойство'''.<br />
<br />
'''Конструктор Класса''' - это просто специальная процедура которая присваивает значения одному или нескольким Полям объекта при его создании по прописанным в неё алгоритмам.<br />
<br />
<br />
=== Дополнительно ===<br />
* '''Атрибуты Поля''' (свойства Переменной Класса) - Переменные кроме своего значения и свойства ТИП, имеют ещё (Свойство) '''&ВидноВсем'''. Чтобы отличать свойства объекта и свойства переменных, свойства переменных называются Атрибуты.<br />
** '''&ВидноВсем''' - без этого Атрибута Поля (переменной) поле было бы видно только тем методам (функциям и процедурам), которые расположены внутри класса. - Т.е. Атрибут ВидоВсем делает из Поля (Переменной) '''Интерфейс''' ?<br />
<br />
== Объявление и создание Класса ==<br />
Рассмотрим определение простейшего класса:<br />
<br />
Класс Животное<br />
//тут можно определить свойства и методы работы с классом<br />
КонецКласса<br />
<br />
Мы можем создавать экземпляры объектов класса Животное оператором '''Новый'''. И несмотря на то, что у этого объекта нет ни каких свойств и методов, ему можно придумать полезное применение. Например, он может быть родителем классов Кошка и Собака.<br />
<br />
'''На заметку:''' Если для класса не указан родитель, то его родителем является класс Объект, который является корневым родителем всей иерархии классов, используемых в .Net.<br />
<br />
=== Добавляем в Класс Переменные - Поля ===<br />
<br />
В языке Перфолента любая информация класса хранится в '''Полях'''.<br />
<br />
'''Поле''' — это переменная, в которой хранится один элемент данных конкретного объекта (экземпляра класса) указанного класса или элемент данных общий для класса.<br />
<br />
Класс Собака<br />
// общее для всех экземпляров класса Поле (переменная) <br />
Объект "Собака1"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Жучка"<br />
Объект "Собака2"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Лайка"<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
Иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
==== '''не проверенное''' ====<br />
<br />
Для программистов: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared (разделяемый между несколькими), т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь ''атрибут'' '''ОбщийДляКласса'''.<br />
<br />
Добавим в наш класс поле Имя:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
КонецКласса<br />
<br />
Теперь мы можем дать собакам имена, например, так:<br />
<br />
Собака1 = '''Новый''' Собака<br />
Собака1.Имя = "Жучка" <br />
Собака2 = '''Новый''' Собака<br />
Собака2.Имя = "Лайка" <br />
<br />
Обратите внимание на ''атрибут поля'' '''ВидноВсем''', без него поле было бы видно только тем методам, которые расположены ''внутри класса''. Подробнее атрибуты видимости членов мы рассмотрим позднее.<br />
<br />
Добавим в класс ещё полей:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
КонецКласса<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
<br />
Теперь наш класс может содержать достаточно информации, что бы можно было создавать объекты, соответствующие конкретным собакам. Однако, иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
Класс Собака Родитель Животное<br />
//поля общие для класса<br />
&ВидноВсем, ОбщийДляКласса Поле КоличествоЭкземпляров тип Целое<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщийВес тип Целое<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам (функциям) описанным внутри класса<br />
&ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата<br />
//-----------------------------------------------<br />
//поля для каждого экземпляра созданных объектов<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам описанным внутри класса<br />
Поле ВремяСозданияОбъекта тип Дата<br />
КонецКласса<br />
<br />
Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.<br />
<br />
=== Задание первоначальных значений переменных (Полей) при создании Объекта (Инициализация полей) ===<br />
<br />
При создании объекта (экземпляра класса) его Поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.<br />
<br />
Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:<br />
<br />
Поле ВремяСозданияОбъекта тип Дата = ТекущаяДата<br />
<br />
Точно так же могут инициализироваться и общие для класса поля, однако тут есть один нюанс. Поле общее для класса буде инициализировано один раз при первом обращении к любому члену этого класса. При создании экземпляра объекта значение общего для класса поля может быть прочитано и/или изменено, например, счетчик создаваемых объектов может быть увеличен на единицу.<br />
<br />
===Поля в интерфейсах.===<br />
<br />
Так как интерфейсы не содержат данных, в них не допустимо определение полей.<br />
<br />
===Поля в структурах.===<br />
<br />
Поля в структурах полностью аналогичны по правилам создания и использования полям классов, описанным выше, за исключением одного нюанса:<br />
инициализация полей структур допустима только для полей общих для класса.<br />
<br />
Структура МояСтруктура<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщееПоле тип Целое = 111 // Правильно. Инициализация допустима.<br />
&ВидноВсем Поле ПриватноеПоле1 тип Целое // Правильно. Нет инициализации.<br />
&ВидноВсем Поле ПриватноеПоле2 тип Целое = 222 // ОШИБКА !!! Инициализация НЕ допустима.<br />
КонецСтруктуры<br />
<br />
===Поля в модулях.===<br />
<br />
Как мы уже знаем, Модуль — это специализированная версия класса, экземпляры объектов которого создавать нельзя, а все члены являются общими для класса.<br />
<br />
Поэтому полям, объявленным в модулях (в том числе в модуле Программа), нет необходимости задавать атрибут ОбщийДляКласса, они и так уже общие.<br />
<br />
Программа МояПрограмма<br />
Поле ВремяСтартаПрограммы тип Дата = ТекущаяДата<br />
КонецПрограммы<br />
<br />
Модуль ОбщиеДанные<br />
&ВидноВсем Поле ОбщаяСтоимость тип Число = 0<br />
КонецМодуля<br />
<br />
=== Поля в перечислениях ===<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова Поле и по умолчанию имеют атрибут ВидноВсем. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
=== Множественное определение полей одного типа.===<br />
<br />
Как и в случае с переменными, несколько полей одного типа можно определить одной строкой кода:<br />
<br />
&ВидноВсем Поле Вес, Рост, ШиринаПлеч, РазмерОбуви, РазмерШапки тип Число = 0<br />
<br />
Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько переменных инициализируется, например:<br />
<br />
Поле Счетчик тип Целое = 0<br />
Поле Один, Два, Три, Четыре, Пять тип Целое = ++Счетчик<br />
// и где-то в методе<br />
ВыводСтроки ""+Один+Два+Три+Четыре+Пять<br />
<br />
На экран консоли будет выведено: 12345.<br />
<br />
<br />
'''Вывод:''' Поле – это единственное средство для хранения данных объекта находящегося в памяти компьютера. Поле обязательно имеет Тип и может быть либо общим для класса, создающимся в одном экземпляре, либо объектным, создающимся в каждом экземпляре объекта. В разных видах элементов программы поля имеют особенности написания и использования во время компиляции и выполнения программы.<br />
<br />
== Наследование (надо ввести понятие ниже)==<br />
Создадим классы Кошка и Собака, указав, что родителем для них является Класс Животное:<br />
<br />
'''Класс''' Кошка '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
'''Класс''' Собака '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
Теперь покажем, как можно эти классы использовать:<br />
<br />
МойКот = '''Новый''' Кот // создадим объект МойКот сложного типа - Кот<br />
ПриветЖивотное(МойКот) // передадим объект МойКот <br />
<br />
МояСобака = '''Новый''' Собака<br />
ПриветЖивотное(МояСобака)<br />
<br />
//где-то ниже определим процедуру<br />
'''Процедура''' ПриветЖивотное(МоёЖивотное '''тип''' Животное) // процедура принимает объект типа Животное<br />
'''Выбор Для''' МоёЖивотное // оператор выбора Выбор Для<br />
'''Когда''' ЭтоТип Кот<br />
'''ВыводСтроки''' "Привет кот!"<br />
'''Когда''' '''ЭтоТип''' Собака<br />
'''ВыводСтроки''' "Привет собака!"<br />
'''Иначе'''<br />
'''ВыводСтроки''' "Привет не известное животное!"<br />
'''КонецВыбора'''<br />
'''КонецПроцедуры'''<br />
<br />
Как видно из этого примера, процедура ПриветЖивотное() может приветствовать животное любого типа, даже такого, который на момент написания программы еще не существовал. Главное, чтобы не известное животное было потомком класса Животное. А вот классы Кот и Собака этой процедуре известны и приветствие выводится вполне конкретное.<br />
<br />
Таким образом, мы извлекли пользу от использования классов не имеющих ни каких свойств и методов (кроме методов родительского типа Объект). Нам пригодилась сама иерархия, согласно которой мы классифицировали объекты.<br />
<br />
Умнику на заметку: Отметьте для себя связь терминов Класс и Классификация. Вы должны выстраивать иерархию классов не как попало, а по определенным критериям, что бы можно было сказать, что вы их классифицировали.<br />
<br />
== Ссылки ==<br />
* [http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language ПРОМОКОД - официальная страница языка программирования Перфолента.NET]<br />
* [http://promcod.com.ua/Article.asp?code=20200902191745030929 ООП на Перфолента.NET часть 1. Терминология: классы, объекты и типы в языке Перфолента]<br />
* [http://promcod.com.ua/Article.asp?code=20200909140544010807 ООП на Перфолента.NET часть 2. Конструируем класс. Поля]<br />
[[Категория:Описание языка Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8397Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:12:42Z<p>Дизайнер: /* Для указания области видимости полей */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования:<br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8396Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:12:31Z<p>Дизайнер: /* Применение атрибутов */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
=== Для указания области видимости полей ===<br />
* &ВидноВсем - к переменной, полю, функции, методу - могут обращаться другие объекты<br />
* ОбщийДляКласса - [[Поле]] существует в 1-м экземпляре, для всех объектов данного типа (Класса)<br />
<br />
Примеры использования <br />
Класс Лампа <br />
// Поля класса <br />
&ВидноВсем Поле Состояние тип Строка = "Выключена" // Переменная <br />
<br />
&ВидноВсем<br />
Функция ИмяФункции <br />
----<br />
КонецФункции<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8395Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T12:03:16Z<p>Дизайнер: /* Написание собственного атрибута и его использование */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - '''АнглийскийСиноним''', а другой встроенный - '''ВидноВсем'''.<br />
<br />
'''АнглийскийCиноним''' процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру т.е. внешняя программа прочитав значение атрибута АнглийскийСиноним у процедуры Старт получит значение "Start" которое сможет использовать по своему усмотрению.<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8394Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:58:59Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования. У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем. Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются:<br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - АнглийскийСиноним, а другой встроенный - ВидноВсем. Английский синоним процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру. <br />
<br />
Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8393Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:57:22Z<p>Дизайнер: /* Написание собственного атрибута и его использование */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются <br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
У атрибута нет логики, он просто хранит несколько параметров, что бы их можно было прочитать в будущем.<br />
<br />
Например, Атрибут - '''АнглийскийСиноним''' может использоваться компилятором, если пользователь вдруг решил писать код на английском языке, тогда компилятор будет искать метод не только по именам, но и по синонимам.<br />
<br />
В стандартной библиотеке Перфоленты почти для всех классов и их членов определены английские синонимы, но компилятор пока ими не умеет ими пользоваться (зарезервировано на будущее) <br />
<br />
Практический смысл создавать атрибуты есть тогда, когда есть необходимость из другой программы анализировать элементы текущей. <br />
<br />
Например:<br />
* редактор формы может показывать в палитре свойств только те свойства формы у которых буде установлен атрибут '''РедактируетсяВПалитреСвойств''' или не будет атрибута '''УстаревшееСвойство'''<br />
<br />
* Программа тестирования может запускать только те методы у которых установлен атрибут '''Тестировать'''.<br />
<br />
* Программа выгрузки класса может выгружать только те поля у которых есть атрибут '''Выгружать''' и т.д. применений можно много найти...<br />
<br />
Определим простейший атрибут '''АнглийскийСиноним''':<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - АнглийскийСиноним, а другой встроенный - ВидноВсем. Английский синоним процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру. <br />
<br />
Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8392Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:52:47Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются <br />
* на стадии компиляции<br />
* на стадии выполнения<br />
Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Применение атрибутов ==<br />
<br />
== Написание собственного атрибута и его использование ==<br />
<br />
Определим простейший атрибут АнглийскийСиноним:<br />
<br />
&ВидноВсем<br />
Класс АнглийскийСиноним Родитель Атрибут<br />
Поле _Синоним тип Строка<br />
&ВидноВсем<br />
Конструктор(Синоним тип Строка)<br />
_Синоним = Синоним<br />
КонецКонструктора<br />
&ВидноВсем<br />
Функция ПолучитьСиноним() тип Строка<br />
Возврат _Синоним<br />
КонецФункции<br />
КонецКласса<br />
<br />
Как видим, кроме наследования от типа Атрибут, других особенностей у класса-атрибута нет.<br />
<br />
Используем созданный нами атрибут АнглийскийСиноним для одного из методов программы - Процедуры Старт:<br />
<br />
&АнглийскийСиноним("Start"), ВидноВсем<br />
Процедура Старт<br />
//тут какой-то код<br />
КонецПроцедуры<br />
<br />
Мы задали для процедуры Старт два атрибута, один созданный нами - АнглийскийСиноним, а другой встроенный - ВидноВсем. Английский синоним процедуры Старт сможет узнать любая программа (в том числе и эта), которая захочет исследовать сборку программы содержащей процедуру. <br />
<br />
Непонятно как использовать Атирбут АнглийскийСиноним, как он влияет на выполнение программы ??<br />
<br />
Во время компиляции создается экземпляр объект указанного класса-атрибута и сохраняется в сборке в области метаданных вместе с элементом программы, который отмечен этим атрибутом. Любой код, который использует сборку может восстановить экземпляр объекта-атрибута и узнать значения его полей и свойств, получая необходимую дополнительную информацию об элементе программы, который был отмечен этим атрибутом.<br />
Список атрибутов располагается перед элементом программы, к которому он принадлежит, начинается с символа & и разделяется запятыми:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН ЭлементПрограммы...<br />
<br />
Для удобства чтения кода обычно ЭлементПрограммы располагают на новой строке вот так:<br />
<br />
&Атрибут1, Атрибут2, АтрибутН<br />
ЭлементПрограммы...<br />
<br />
Каждый отдельный атрибут — это экземпляр объект указанного класса, созданный оператором Новый, с последующим заполнением полей и свойств этого созданного объекта инициализатором, если необходимо.<br />
<br />
В конструктор атрибута можно передать необходимое количество параметров:<br />
<br />
&Новый ContextClass("МойКласс", "MyClass")<br />
Ключевое слово Новый при создании атрибутов не обязательно, просто помните, что оно там присутствует неявно:<br />
<br />
&ContextClass("МойКласс", "MyClass")<br />
<br />
После вызова конструктора можно заполнить значения полей и свойств атрибута с помощью инициализатора:<br />
<br />
&Новый ИмпортМетода("kernel32.dll") { .EntryPoint="SetConsoleTitleW", .CharSet=CharSet.Auto, .SetLastError=True}<br />
<br />
Значениями параметров конструктора, полей и свойств могут быть только константные не изменяемые в дальнейшем выражения, вычисляемые при компиляции.<br />
<br />
//в этом атрибуте проверим вычисление константных выражений в параметрах<br />
&EnumerationType("Виды"+"Операци"+"и"с, "Operation"+"Types", Не Ложь)<br />
<br />
Для встроенных атрибутов, например, таких, как атрибуты видимости членов, можно использовать стандартный синтаксис, но смысла в этом нет:<br />
<br />
&Новый ВидноВсем(){}, Новый ВидноСборке(){}<br />
<br />
Пустые круглые и фигурные скобки, как и ключевое слово Новый не обязательны:<br />
<br />
&ВидноВсем, ВидноСборке<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8391Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:46:51Z<p>Дизайнер: /* Использование атрибутов (.NET Framework) */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Атрибуты NET Framework и их использование ==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8390Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:46:11Z<p>Дизайнер: /* = Атрибуты модуля сборки (.NET) */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Использование атрибутов (.NET Framework)==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
=== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8389Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:45:38Z<p>Дизайнер: /* Устройство атрибута */</p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Встроенные атрибуты языка Перфолента ==<br />
<br />
В язык Перфолента встроены следующие атрибуты:<br />
<br />
* '''ВидноВсем''', '''ВидноСборке''', '''ВидноНаследникам''', '''ВидноНаследникамСборки''' - атрибуты видимости классов и их членов;<br />
<br />
* '''ПространствоИмен'''("МоёПространство "), ПространствоИмён("МоёПространство") (синонимы) - атрибут класса, определяющий пространство имен, к которому принадлежит класс;<br />
<br />
* '''ОднопоточнаяМодель''', '''МногопоточнаяМодель''' - атрибуты метода Старт, определяющие модель взаимодействия для COM объектов;<br />
<br />
* '''ОбщийДляКласса''' - атрибут члена класса (Поля, Метода) делающий его общим для всех созданных экземпляров объектов этого класса;<br />
<br />
* '''Глобальный''' - атрибут модуля, определяющий доступ всех видимых ко всем видимым членам модуля из всех других методов программы; <br />
<br />
* '''Сериализуемый''' – атрибут класса, указывающий компилятору необходимость создать код поддержки сериализации данных класса; ссылка в вики на сериализация класса<br />
<br />
* '''ДолженНаследоваться''', '''МожетНаследоваться''', '''НеМожетНаследоваться''' - атрибуты класса, определяющие возможность или необходимость его наследования;<br />
<br />
* '''ДолженПереопределяться''', '''МожетПереопределяться''', '''НеМожетПереопределяться''' - атрибуты члена класса (Поле, Метод,), определяющие возможность или необходимость его переопределения;<br />
<br />
* '''Переопределение''' - атрибут переопределения метода родителя в классе-наследнике;<br />
<br />
* '''Перекрытие''' - атрибут перекрытия метода родителя в классе-наследнике;<br />
<br />
* '''Перегрузка''' - атрибут перегрузки методов с одинаковыми именами;<br />
<br />
* '''ТолькоЧтение''', '''ТолькоЗапись''' - атрибуты ограничения доступа к полям и свойствам;<br />
<br />
* '''Обработчик'''("МоёСобытие") - атрибут метода класса (процедуры), определяющий, что метод является обработчиком указанного события;<br />
<br />
* '''ИмпортМетода''' – специальный атрибут метода, указывающий компилятору, что реализация метода находится во внешней библиотеке и имеет указанную сигнатуру;<br />
<br />
Назначение и особенности использования встроенных атрибутов подробнее рассматриваются в тех статьях, где описаны сущности языка, к которым <br />
применяются конкретные атрибуты<br />
<br />
== Использование атрибутов (.NET Framework)==<br />
<br />
=== Атрибуты сборки (.NET) ===<br />
В .Net определены разнообразные атрибуты, которые есть смысл применять к сборке в определенных ситуациях. Этот вид атрибутов желательно задавать в начале программы на уровне классов. <br />
<br />
АтрибутСборки System.Runtime.InteropServices.ComVisible(Ложь)<br />
<br />
==== Атрибуты модуля сборки (.NET) ===<br />
В .Net определены несколько атрибутов, которые есть смысл применять к модулю сборки в определенных ситуациях (не путайте модуль сборки с модулями программы). Этот вид атрибутов желательно задавать в начале программы на уровне классов.<br />
<br />
АтрибутМодуля System.CLSCompliant(Истина)<br />
<br />
=== Атрибуты параметров метода. ===<br />
<br />
Не только сами методы могут иметь атрибуты, но и их параметры. Для параметров используется тот же синтаксис атрибутов, как и для других элементов программы.<br />
<br />
&ВидноВсем<br />
Функция СобратьБит32( &АнглСиноним("HighDigits") Знач СтаршиеРазряды тип Бит16,<br />
&АнглСиноним("LowDigits") Знач МладшиеРазряды тип Бит16<br />
) &АнглСиноним("ReturnValue") тип Бит32 //к возвращаемому параметру тоже можно применить атрибуты<br />
Возврат (Бит32(СтаршиеРазряды) << 16) БитИли МладшиеРазряды<br />
КонецФункции<br />
<br />
=== Определение особого порядка и правил передачи полей структуры (NET)===<br />
<br />
Структуры, которые необходимо передавать коду, написанному на языках подобных C, C++, Rust, чаще всего необходимо отметить атрибутом StructLayout заставляющем среду исполнения сформировать структуру пригодную к передаче. Также необходимо убедиться, что правильно передаются поля имеющие сложный тип, такие как массивы или другие структуры. Для задания правил передачи используется атрибут MarshalAs. Ознакомьтесь с документацией .Net по этим атрибутам, прежде, чем передавать структуры в код, написанный на указанных языках.<br />
<br />
&StructLayout(LayoutKind.Sequential){ .Pack=1, .CharSet=CharSet.Auto }<br />
Структура UDT<br />
&ВидноВсем Поле rxStatus тип Цел16<br />
&ВидноВсем Поле datalen тип Байт<br />
<br />
&ВидноВсем, MarshalAs(UnmanagedType.ByValArray){ .SizeConst=255 }<br />
Поле array1 тип Байт[]<br />
<br />
&ВидноВсем<br />
Процедура Инициализировать()<br />
//код инициализации<br />
КонецПроцедуры<br />
<br />
КонецСтруктуры<br />
<br />
=== Наиболее актуальные случаи применения атрибутов (NET)===<br />
# Пометить метод атрибутом WebMethod в Web сервисах, для указания, что метод должен вызываться через SOAP протокол.<br />
# Описание способа передачи параметров метода в не управляемый код с помощью атрибута System.Runtime.InteropServices.MarshalAs.<br />
# Описание свойств COM для классов, методов и интерфейсов.<br />
# Вызов методов неуправляемого кода с помощью атрибута System.Runtime.InteropServices.DllImport (синоним ИмпортМетода).<br />
# Описание свойств сборки, таких как, версия, заголовок, копирайт и т.д., с помощью группы атрибутов подобных System.Reflection.AssemblyTitle.<br />
# Пометка членов класса, которые могут быть сериализованы с помощью атрибута System.Serializable (синоним Сериализуемый).<br />
# Описание сопоставления между членами класса и узлами XML для сериализации объекта в XML.<br />
# Описание требований безопасности для методов.<br />
# Указание характеристик, используемых для обеспечения безопасности.<br />
# Установка параметров JIT компиляции, например, для сохранения удобства отладки.<br />
# Получение информации о вызывающем методе.<br />
# Указание на то, что метод или другой элемент программы устарел с помощью атрибута System.Obsolete.<br />
<br />
Использование атрибутов в указанных случаях описано в документации .Net.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8388Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T11:37:12Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены:<br />
* в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков<br />
* в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку <br />
* Вами в вашей программе и использовать их будете только Вы<br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8387Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T10:41:57Z<p>Дизайнер: </p>
<hr />
<div>В языке [[Перфолента.Net]] можно привязать к элементам программы дополнительную информацию, которая придаст им дополнительный смысл, особое назначение или особые правила использования.<br />
<br />
В языке Перфолента, как и в других .Net языках, атрибуты элементов программы используются как на стадии компиляции, так и на стадии выполнения. Это значит, что как компилятор может внести изменения в генерируемый машинный код основываясь на атрибутах, так и выполняющаяся программа может менять своё поведение в зависимости от атрибутов выполняемого кода.<br />
<br />
Процесс получения атрибутов сборки и других элементов программы называется рефлексией (reflection).<br />
<br />
== Виды атрибутов ==<br />
Итак, '''Атрибуты''' могут влиять на:<br />
* сборку (компиляцию) программы<br />
* выполнение кода программы<br />
<br />
Атрибуты могут быть определены<br />
* в платформе NET<br />
* в Языке Перфолента<br />
* могут быть определены программистом <br />
<br />
Часть используемых вами атрибутов определена прямо в языке Перфолента (в стандартной библиотеке ??), это:<br />
* видимости (ВидноВсем),<br />
* наследования, <br />
* переопределения методов <br />
* и другие (ТолькоДляЧтения). <br />
<br />
С каждым из них мы познакомимся чуть позже.<br />
<br />
Некоторые атрибуты определены в библиотеке Net Framework и могут использоваться компиляторами любых .Net языков. <br />
<br />
Другие атрибуты определены в стандартной библиотеке Перфоленты и могут использоваться компилятором Перфоленты и программами, использующими эту библиотеку. <br />
<br />
А некоторые атрибуты будут определены Вами в вашей программе и использовать их будете только Вы.<br />
<br />
Важно: в языке 1С, как и в некоторых других языках программирования, '''атрибуты''' называют '''аннотациями'''. В разных языках синтаксис записи атрибутов (аннотаций) различен, как и способы их использования, но в большинстве современных языков они в том или ином виде есть.<br />
<br />
== Устройство атрибута ==<br />
<br />
Технически, атрибуты — это специальные классы, унаследованные от класса Атрибут, который в .Net соответствует классу System.Attribute.<br />
Атрибуты могут что-то значить сами по себе или иметь конструктор, принимающий на хранение дополнительную информацию в виде параметров. Типы параметров конструктора атрибута, а также полей и свойств, ограничены в .Net следующими типами: <br />
Цел8, Цел32, Цел64, Байт, Бит32, Бит64, Вещ, ДВещ, Строка, Символ, Булево, Тип,<br />
а также это может быть Перечисление одного из указанных типов.<br />
К сожалению, платформа .Net не поддерживает тип Дата в качестве параметра атрибута, но при необходимости дату (как и другие сериализуемые типы) можно представлять строкой.<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D1%8B_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B&diff=8386Перфолента.NET. ООП. Атрибуты элементов программы2020-11-12T10:08:13Z<p>Дизайнер: Новая страница: « Категория:Перфолента.NET. Описание языка Перфолента.NET Категория:Перфолента.NET. Объек…»</p>
<hr />
<div><br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET._%D0%9E%D0%9E%D0%9F._%D0%9A%D0%BE%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%B8%D1%80%D1%83%D0%B5%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%81._%D0%A1%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0._%D0%A7%D0%B0%D1%81%D1%82%D1%8C_1._%D0%A3%D0%BF%D1%80%D0%BE%D1%89%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5&diff=8385Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание2020-11-12T10:00:42Z<p>Дизайнер: </p>
<hr />
<div>'''Конструируем класс. Свойства. Часть 1.''' <br />
<br />
Упрощено, на основе оригинального [[Перфолента.NET. ООП. Конструируем класс. Свойства]]<br />
<br />
== Введение ==<br />
<br />
Свойство объекта - это присущее ему качество, характеристика или признак. Однако на уровне программного кода свойства всего лишь позволяют установить контроль над процессом установки значений полей. Синтаксис свойств и их использование рассмотрены в этой статье.<br />
<br />
Необходимо проверять значения устанавливаемых свойств, иначе можно получить не корректно работающий объект.<br />
<br />
Рассматривая конструирование собственных классов, мы уже ознакомились с полями и конструкторами и узнали, что:<br />
<br />
* все данные объекта хранятся в полях<br />
* конструкторы помогают заполнить начальные значения полей удобным и не противоречивым образом.<br />
<br />
На первый взгляд этого достаточно, чтобы можно было создавать объекты на основе классов и успешно их использовать. Так и есть, однако, <br />
современные программы достаточно велики и содержат множество классов, зачастую написанных разными людьми и даже людьми из разных организаций <br />
и разных стран. Программист, использующий класс, чаще всего не знает подробности его реализации, в частности, ему трудно оценить, изменение <br />
каких полей должно происходить согласованно. Еще одна проблема состоит в том, что программист не знает диапазона допустимых значений для <br />
используемых полей и может присвоить полю значение нарушающее корректную работу объекта.<br />
<br />
Выход нашелся довольно быстро. Критичные Поля надо скрыть, а получать и устанавливать значения скрытых полей надо с помощью методов, в <br />
которых можно производить проверку значений и выполнять согласованные изменения полей.<br />
<br />
Отлично, это работает и решает все проблемы, кроме одной, то что логически выглядит как Свойство (характеристики) объекта больше не доступно <br />
для изменения и даже скрыто от внешнего наблюдателя. Вместо Свойство объект получает множество методов в лучшем случае начинающихся со слов <br />
Получить и Установить. Например:<br />
<br />
Получить_ИмяСобаки(), Установить Имя_Собаки()<br />
<br />
Не красиво, не удобно, громоздко.<br />
<br />
Для решения проблемы было предложено ввести новое понятие – Свойство, которое объединило достоинства обоих подходов. Свойство выглядит для <br />
внешнего наблюдателя и программиста как поле, но для получения и корректной установки значения имеет соответствующие методы, в которых можно <br />
выполнить проверку значения и выполнить другие необходимые действия при его изменении.<br />
<br />
Конечно, такое решение потребовало доработки компилятора, который теперь обязан сам определять, где идет обращение к полю, а где к свойству, <br />
и для свойства компилятор должен вызывать соответствующие методы.<br />
<br />
== Свойства==<br />
<br />
Свойство можно представить, как своеобразную «обёртку» над полем. Свойство имеет оба или только один из методов Получить/Установить, а также <br />
может иметь одно или несколько полей для хранения связанных с ним данных. Свойство может не иметь «своих» полей, а оказывать влияние на поля <br />
других свойств или на поля, логически не связанные со свойствами, но такое поведение встречается довольно редко.<br />
<br />
В языке Перфолента для создания свойства существуют два разных синтаксиса – полный и краткий (авто). <br />
<br />
* Полный позволяет контролировать все аспекты работы свойства, но содержит много кода по сравнению с полем. <br />
* Краткий способ (авто) позволяет компилятору автоматически добавить скрытое поле для хранения значения и дописать код методов <br />
Получить/Установить, делая синтаксис определения свойства почти не отличимым от определения поля.<br />
<br />
Что бы понять конструкцию свойства сначала рассмотрим полный синтаксис:<br />
<br />
Класс Собака <br />
&ВидноВсем<br />
Свойство Полное ИмяСобаки тип Строка<br />
// скрытое поле “_ИмяСобаки” для хранения значения свойства “ИмяСобаки”<br />
// скрытое поле должно начинаться со знака подчёркивания + ИмяСвойства<br />
Поле _ИмяСобаки тип Строка = "Без имени"<br />
// метод Получить для получения значения свойства ИмяСобаки<br />
Получить<br />
Возврат _ИмяСобаки<br />
КонецПолучить<br />
//метод Установить для установки значения свойства ИмяСобаки<br />
Установить(НовоеИмя тип Строка)<br />
// Какие-то проверки корректности присваиваемого значения<br />
_ИмяСобаки = НовоеИмя<br />
КонецУстановить<br />
КонецСвойства<br />
КонецКласса<br />
<br />
Пояснения к коду:<br />
<br />
* ключевое слово Полное в этом примере является обязательным<br />
* названия методов Получить и Установить являются зарезервированными<br />
* Скрытое Поле обычно начинаться со знака подчёркивания + ИмяСвойства<br />
* при операции присваивания ИмяСобаки = “Жучка” автоматически (и скрыто от программиста т.е. не явно) будет вызван метод Установить <br />
(“Жучка”)<br />
* Если в методе обратится напрямую _ИмяСвойства = “Какое-то значения” то присваивание нового значения будет без использования проверок <br />
из метода Установить. Это верно только для методов находящихся внутри данного, т.к. для методов снаружи класса поле не видно, если у него <br />
нет атрибута &ВидноВсем… <br />
<br />
Как видите, по сравнению с полем кода стало значительно больше. Однако, у нас появилось два метода Получить и Установить, в которых мы можем <br />
делать любые проверки, например, корректно ли новое значение, или можем выполнить какие-то действия необходимые при изменении значения <br />
свойства.<br />
<br />
== ПРИМЕР ИСПОЛЬЗОВАНИЯ: Как работает метод '''Установить''' ==<br />
<br />
СобакаМаши = Новый Собака // создаём объект СобакаМаши по образцу класса Собака<br />
СобакаМаши.ИмяСобаки = "Шарик" // Присваиваем свойству ИмяСобаки значение “Шарик”<br />
<br />
Что при этом происходит? Мы присваиваем свойству ИмяСобаки значение также, как если бы это было Поле. Но при присваивании, скрытно (у <br />
программистов для этого есть специальный термин - “неявно”) вызывается метод Установить (имя метода “Установить” – специально <br />
зарезервировано в языке программирования для присваивания значений свойствам)<br />
<br />
Установить(НовоеИмя тип Строка)<br />
// Какие-то проверки корректности присваиваемого значения<br />
// например что длина имени от 2 до 15 символов <br />
_ИмяСобаки = НовоеИмя<br />
КонецУстановить<br />
<br />
При неявном (скрытом) вызове метода Установить значение “Шарик” передаётся в качестве параметра НовоеИмя метода Установить т.е. <br />
<br />
Установить(“Шарик”)<br />
<br />
Метод Установить приводит присвоение значения переменной НовоеИмя = ”Шарик”, скрытому Полю _ИмяСобаки. Коряво…<br />
<br />
Для удобства программистов (чтобы всегда было просто определит какому свойству соответствует какое имя скрытого Поля) Имя поля выбирается <br />
добавлением “_” (знака подчёркивания) к имени Свойства.<br />
<br />
“_” + ИмяСвойства = _ИмяСкрытогоПоля<br />
<br />
При этом перед присвоением в Методе Установить можно сделать различные проверки на корректность присваиваемого значения. Поле _ИмяСобаки – <br />
имеет тип Строка – соответственно если мы ему присвоим значение “8ВА$” или “Собака соседки из соседнего подъезда” – то ошибки не будет, но <br />
очевидно, что эти значения именами собаки является не могут. Необходимы дополнительные проверки. Самое просто в данном случае – проверить <br />
длину имени (оно должна состоять от 2 до максимум 15 символов). Ещё можно проверить на то, что в имени присутствуют только буквы и нет <br />
символов “$ ? !” и т.п.<br />
<br />
Если замечены ошибки, то необходимо сгенерировать сообщение, чтобы программист видел в каком месте программы и ошибка какого типа произошла. <br />
Это гораздо проще чем потом выяснять почему в базе данных при запросе не появляется имя собаки клиента с именем “8ВА$”, или происходит <br />
ошибка при записи в базу данных имени “ Собака соседки из соседнего подъезда” т.к. там стоит ограничение на длину имени в 15 символов.<br />
<br />
Затем можно нормализовать имя если пользователь присвоил его не точно. Например, “шАрИк” или “шарик” можно преобразовать к “Шарик”.<br />
<br />
При необходимости можно напрямую присвоить значение скрытому Полю, минуя проверки метода Установить. В основном это требуется для отладки <br />
объектов.<br />
<br />
СобакаМаши._ИмяСобаки = "Шарик" <br />
// Присваиваем Скрытому Полю ИмяСобаки значение “Шарик” минуя проверки метода Установить <br />
<br />
'''Важно''': Методы Установить (и Получить) неявные – т.е. они автоматически вызываются когда присваивается значение свойству (или читается <br />
значение свойства).<br />
<br />
СобакаМаши.ИмяСобаки = "Шарик" // в момент выполнения операции = “Шарик” автоматически вызывается метод Установить которому передаётся <br />
значение “Шарик” и который присваивает его (после проверок) значению поля _ИмяСобаки<br />
<br />
Нельзя в явном виде вызвать методы Установить (и Получить), например:<br />
<br />
СобакаМаши.ИмяСобаки.Установить = "Шарик" // Ошибка<br />
<br />
или<br />
<br />
СобакаМаши.ИмяСобаки.Установить ("Шарик") // Ошибка<br />
<br />
== ПРИМЕР ИСПОЛЬЗОВАНИЯ: Как работает метод '''Получить''' ==<br />
<br />
Вернёмся к нашему классу Собака<br />
<br />
Класс Собака <br />
&ВидноВсем<br />
Свойство Полное ИмяСобаки тип Строка<br />
// скрытое поле “_ИмяСобаки” для хранения значения свойства “ИмяСобаки”<br />
// скрытое поле должно начинаться со знака подчёркивания + ИмяСвойства<br />
Поле _ИмяСобаки тип Строка = "Без имени"<br />
// метод Получить для получения значения свойства ИмяСобаки<br />
Получить<br />
Возврат _ИмяСобаки<br />
КонецПолучить<br />
//метод Установить для установки значения свойства ИмяСобаки<br />
Установить(НовоеИмя тип Строка)<br />
// Какие-то проверки корректности присваиваемого значения<br />
_ИмяСобаки = НовоеИмя<br />
КонецУстановить<br />
КонецСвойства<br />
КонецКласса<br />
<br />
Чтобы получить значение Свойства ИмяСобаки <br />
<br />
СобакаМаши = Новый Собака // создаём объект СобакаМаши по образцу класса Собака<br />
СобакаМаши.ИмяСобаки = "Шарик" // Присваиваем свойству ИмяСобаки значение “Шарик”<br />
ВыводСтроки СобакаМаши.ИмяСобаки // Тут будет вызван метод Получить, который вернёт значение ”Шарик”<br />
<br />
При вызове оператора ВыводСтроки происходит обращение к объекту СобакаМаши и её Свойству ИмяСобаки. При попытке прочитать значение Свойства <br />
ИмяСобаки у объекта СобакаМаши происходит скрыто (неявно) в вызов метода Получить<br />
<br />
// метод Получить для получения значения свойства ИмяСобаки<br />
Получить<br />
Возврат _ИмяСобаки<br />
КонецПолучить<br />
<br />
При вызове метода Получить для свойства ИмяСобаки происходит обращение к скрытому Полю _ИмяСобаки, чтение его содержимого и передача его <br />
значения с помощью ключевого слова Возврат -> Свойству ИмяСобаки и далее -> оператору ВыводСтроки для отображения на экране.<br />
<br />
Перед выдачей значения Поля _ИмяСобаки оператором Возврат с этим значением можно провести некоторые операции например перевести Имя Собаки <br />
в верхний регистр “Шарик” ->”ШАРИК” или добавить описание:<br />
<br />
Возврат “Имя Собаки : ” + _ИмяСобаки<br />
<br />
Т.о. на экране появится не “Шарик”, а “ШАРИК” или “Имя Собаки : Шарик” <br />
<br />
Можно напрямую прочитать значение поля _ИмяСобаки например так:<br />
<br />
ВыводСтроки СобакаМаши._ИмяСобаки это не верно, если используется снаружи класса…<br />
<br />
При этом мы получим значение Поля _ИмяСобаки минуя всякие обработки метода Получить.<br />
<br />
== Запрет на чтение и запись свойств ==<br />
<br />
Если при объявлении Свойства не указать метод Установить - то присваивание значения этому Свойству ПОСЛЕ ИНИЦИАЛИЗАЦИИ будет невозможно. Это <br />
аналогично создания Свойства “только для чтения” – обычно это применяется для свойств значение которых не должно манятся после создания <br />
например: Артикул Товара, уникальный номер или код который присваивается при создании объекта по которому один объект можно легко отличить <br />
от другого, Фамилия, Имя и Отчество, дата рождения, номера документов и т.п.<br />
<br />
Если при объявлении Свойства не указать метод Получить то получение значения этого Свойства будет невозможно т.к. отсутствует <br />
соответствующий метод. Т.о. Свойство получается “только для Записи”. Зачем это необходимо? Например, если в поле записан Пароль учётной <br />
записи пользователя – имеет смысл запретить читать его кому попало.<br />
<br />
Все эти запреты сделаны для удобства и исключения ошибок самими программистами, а не для защиты от хакеров. Мы всегда сможем напрямую <br />
прочитать или записать значение Поля, связанного со Свойством. Это верно только для методов находящихся внутри класса, т.к. для методов <br />
снаружи класса поле не видно, если у него нет атрибута &ВидноВсем…<br />
<br />
Например так:<br />
<br />
СобакаМаши._ИмяСобаки = "Шарик" <br />
<br />
ВыводСтроки СобакаМаши._ИмяСобаки<br />
<br />
== Ссылки ==<br />
* [[Описание языка Перфолента.NET]]<br />
* http://promcod.com.ua/Article.asp?code=20200916124335059953 - Первоисточник<br />
<br />
<br />
[[Категория:Перфолента.NET. Описание языка Перфолента.NET]]<br />
[[Категория:Перфолента.NET. Объектно-Ориентированное Программирование]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%90%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82&diff=8384Атрибут2020-11-12T09:59:54Z<p>Дизайнер: Перенаправление на Перфолента.NET. ООП. Атрибуты элементов программы</p>
<hr />
<div>#перенаправление [[Перфолента.NET. ООП. Атрибуты элементов программы]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5_%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8383Объектно-ориентированное программирование на языке Перфолента.NET2020-11-12T09:59:16Z<p>Дизайнер: </p>
<hr />
<div><br />
== Копия официального описания ООП на Перфолента.NET (можно править и дополнять) ==<br />
* [[Перфолента.NET. ООП. Терминология: классы, объекты и типы в языке Перфолента]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Поля]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Конструкторы]]<br />
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]<br />
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального<br />
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]<br />
<br />
== Упрощенное описание ООП (Не править в процессе написания)==<br />
Для понимания темы Вам необходимо понимать что такое Функция и Процедура. Как их использовать.<br />
* см. [[Объектно Ориентированное-Программирование простое описание]]<br />
<br />
== Используемые, но не введённые понятия (временный раздел для редактирования) ==<br />
* Интерфейс<br />
* Конструктор (из примера кода)<br />
* Наследование<br />
* Структура<br />
* Поле - переменная Объекта<br />
Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями... <br />
* [[Атрибут]] Поля - свойство переменной<br />
** &ВидноВсем - к переменной могут обращаться другие объекты<br />
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)<br />
<br />
=== Перечисления ===<br />
<br />
* [[Перечисления]] - Перечислимый тип данных, т.е. переменные этого типа данных - могут принимать всего несколько значений которые перечислены при объявления типа.<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова '''Поле''' и по умолчанию имеют атрибут '''ВидноВсем'''. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
== Определения Класса и связанных понятий ==<br />
<br />
'''Важно''': <br />
* Классы объявляются после конца программы (после оператора '''КонецПрограммы''').<br />
* Функции и процедуры объявляются в самом конце программы между операторами '''КонецПроцедуры''' (Старт) и '''КонецПрограммы'''.<br />
<br />
'''Класс''' - это составной тип, который, для удобства программиста, логические объединяет вместе переменный, процедуры и функции которые эти переменные используют. Аналогом класса в процедурном программировании является ТИП переменной.<br />
<br />
Класс состоит из:<br />
* Переменные - чтобы отличать их от обычных переменных в классах они называются '''Поля''' или '''Свойства''' (объекта).<br />
* Функции и Процедуры использующие эти переменные - чтобы отличать их от обычных функций и процедур в классах они называются '''Методы''' и '''События''' (функции которые реагируют на внешние по отношению к объекту события, например пользователь Щёлкает по кнопке "Закрыть окно")<br />
<br />
'''Объект''' - это один экземпляр класса, т.е. Класс это "штамп" из заготовок переменных и привязанных к ним процедур которые работают с этими переменными.<br />
<br />
Чем отличается Переменная от Поля ? <br />
* Переменная - используется при вычислениях внутри Функции или Процедуры. Как только процедура или функция завершила свою работу и передала результат работы в то место программы откуда её вызвали, то все используемые ей переменные уничтожаются, чтобы не занимать память.<br />
* Поле - это "переменная" используемая внутри объектов. Сточки зрения компилятора она организованна совсем по другому. В Поле одного объекта может писать или читать другой объект (если ему разрешать читать или писать в поле принадлежащее другому объекту). Поле гораздо более мощная конструкция, при создании поля программист может не только указать Тип хранящегося в нём значения, но и разрешить или запретить другим методом других объектов читать содержащееся в этом Поле значения.<br />
<br />
А если при использования '''Поля''' другой объект попытается записать в '''Поле''' "переменную правильного типа, но неправильного значения" или у объекта необходимо изменять несколько '''Полей''' синхронно или по определённому алгоритму ?<br />
<br />
Для этого к выбранному '''Полю''' можно добавить 2 специальных метода со стандартными именами '''Прочитать''' и '''Установить'''. При попытке прочитать значение этого поля или записать в него какое либо значение автоматически будут вырываться соответствующие методы '''Прочитать''' и '''Установить''' - внутри которых будут прописаны соответствующие алгоритмы по проверке значения присваиваемых переменных и/или синхронному изменению значений нескольких Полей этого объекта. Чтобы отличить такое "Поле" от обычных его называют - '''Свойство'''.<br />
<br />
'''Конструктор Класса''' - это просто специальная процедура которая присваивает значения одному или нескольким Полям объекта при его создании по прописанным в неё алгоритмам.<br />
<br />
<br />
=== Дополнительно ===<br />
* '''Атрибуты Поля''' (свойства Переменной Класса) - Переменные кроме своего значения и свойства ТИП, имеют ещё (Свойство) '''&ВидноВсем'''. Чтобы отличать свойства объекта и свойства переменных, свойства переменных называются Атрибуты.<br />
** '''&ВидноВсем''' - без этого Атрибута Поля (переменной) поле было бы видно только тем методам (функциям и процедурам), которые расположены внутри класса. - Т.е. Атрибут ВидоВсем делает из Поля (Переменной) '''Интерфейс''' ?<br />
<br />
== Объявление и создание Класса ==<br />
Рассмотрим определение простейшего класса:<br />
<br />
Класс Животное<br />
//тут можно определить свойства и методы работы с классом<br />
КонецКласса<br />
<br />
Мы можем создавать экземпляры объектов класса Животное оператором '''Новый'''. И несмотря на то, что у этого объекта нет ни каких свойств и методов, ему можно придумать полезное применение. Например, он может быть родителем классов Кошка и Собака.<br />
<br />
'''На заметку:''' Если для класса не указан родитель, то его родителем является класс Объект, который является корневым родителем всей иерархии классов, используемых в .Net.<br />
<br />
=== Добавляем в Класс Переменные - Поля ===<br />
<br />
В языке Перфолента любая информация класса хранится в '''Полях'''.<br />
<br />
'''Поле''' — это переменная, в которой хранится один элемент данных конкретного объекта (экземпляра класса) указанного класса или элемент данных общий для класса.<br />
<br />
Класс Собака<br />
// общее для всех экземпляров класса Поле (переменная) <br />
Объект "Собака1"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Жучка"<br />
Объект "Собака2"<br />
// Поле (Переменная) индивидуальная для каждого объекта<br />
Имя = "Лайка"<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
Иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
==== '''не проверенное''' ====<br />
<br />
Для программистов: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared (разделяемый между несколькими), т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь ''атрибут'' '''ОбщийДляКласса'''.<br />
<br />
Добавим в наш класс поле Имя:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
КонецКласса<br />
<br />
Теперь мы можем дать собакам имена, например, так:<br />
<br />
Собака1 = '''Новый''' Собака<br />
Собака1.Имя = "Жучка" <br />
Собака2 = '''Новый''' Собака<br />
Собака2.Имя = "Лайка" <br />
<br />
Обратите внимание на ''атрибут поля'' '''ВидноВсем''', без него поле было бы видно только тем методам, которые расположены ''внутри класса''. Подробнее атрибуты видимости членов мы рассмотрим позднее.<br />
<br />
Добавим в класс ещё полей:<br />
<br />
Класс Собака Родитель Животное<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
КонецКласса<br />
<br />
==== Общее Для всех объектов (Экземпляров Класса) Поле ====<br />
<br />
Теперь наш класс может содержать достаточно информации, что бы можно было создавать объекты, соответствующие конкретным собакам. Однако, иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.<br />
<br />
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.<br />
<br />
Класс Собака Родитель Животное<br />
//поля общие для класса<br />
&ВидноВсем, ОбщийДляКласса Поле КоличествоЭкземпляров тип Целое<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщийВес тип Целое<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам (функциям) описанным внутри класса<br />
&ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата<br />
//-----------------------------------------------<br />
//поля для каждого экземпляра созданных объектов<br />
&ВидноВсем Поле Имя тип Строка<br />
&ВидноВсем Поле ДатаРождения тип Дата<br />
&ВидноВсем Поле Вес тип Целое<br />
&ВидноВсем Поле Цвет тип Строка<br />
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили<br />
//это поле не имеет атрибута ВидноВсем и будет видно только методам описанным внутри класса<br />
Поле ВремяСозданияОбъекта тип Дата<br />
КонецКласса<br />
<br />
Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.<br />
<br />
=== Задание первоначальных значений переменных (Полей) при создании Объекта (Инициализация полей) ===<br />
<br />
При создании объекта (экземпляра класса) его Поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.<br />
<br />
Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:<br />
<br />
Поле ВремяСозданияОбъекта тип Дата = ТекущаяДата<br />
<br />
Точно так же могут инициализироваться и общие для класса поля, однако тут есть один нюанс. Поле общее для класса буде инициализировано один раз при первом обращении к любому члену этого класса. При создании экземпляра объекта значение общего для класса поля может быть прочитано и/или изменено, например, счетчик создаваемых объектов может быть увеличен на единицу.<br />
<br />
===Поля в интерфейсах.===<br />
<br />
Так как интерфейсы не содержат данных, в них не допустимо определение полей.<br />
<br />
===Поля в структурах.===<br />
<br />
Поля в структурах полностью аналогичны по правилам создания и использования полям классов, описанным выше, за исключением одного нюанса:<br />
инициализация полей структур допустима только для полей общих для класса.<br />
<br />
Структура МояСтруктура<br />
&ВидноВсем, ОбщийДляКласса Поле ОбщееПоле тип Целое = 111 // Правильно. Инициализация допустима.<br />
&ВидноВсем Поле ПриватноеПоле1 тип Целое // Правильно. Нет инициализации.<br />
&ВидноВсем Поле ПриватноеПоле2 тип Целое = 222 // ОШИБКА !!! Инициализация НЕ допустима.<br />
КонецСтруктуры<br />
<br />
===Поля в модулях.===<br />
<br />
Как мы уже знаем, Модуль — это специализированная версия класса, экземпляры объектов которого создавать нельзя, а все члены являются общими для класса.<br />
<br />
Поэтому полям, объявленным в модулях (в том числе в модуле Программа), нет необходимости задавать атрибут ОбщийДляКласса, они и так уже общие.<br />
<br />
Программа МояПрограмма<br />
Поле ВремяСтартаПрограммы тип Дата = ТекущаяДата<br />
КонецПрограммы<br />
<br />
Модуль ОбщиеДанные<br />
&ВидноВсем Поле ОбщаяСтоимость тип Число = 0<br />
КонецМодуля<br />
<br />
=== Поля в перечислениях ===<br />
<br />
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова Поле и по умолчанию имеют атрибут ВидноВсем. Указывать тип полей нельзя, т.к. все они имеют тип перечисления. А вот инициализация полей перечисления в языке Перфолента необходима.<br />
<br />
Перечисление ПородыСобак тип Целое<br />
Овчарка = 1<br />
Бульдог = 2<br />
Такса = 3<br />
Доберман = 4<br />
//...<br />
КонецПеречисления<br />
<br />
=== Множественное определение полей одного типа.===<br />
<br />
Как и в случае с переменными, несколько полей одного типа можно определить одной строкой кода:<br />
<br />
&ВидноВсем Поле Вес, Рост, ШиринаПлеч, РазмерОбуви, РазмерШапки тип Число = 0<br />
<br />
Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько переменных инициализируется, например:<br />
<br />
Поле Счетчик тип Целое = 0<br />
Поле Один, Два, Три, Четыре, Пять тип Целое = ++Счетчик<br />
// и где-то в методе<br />
ВыводСтроки ""+Один+Два+Три+Четыре+Пять<br />
<br />
На экран консоли будет выведено: 12345.<br />
<br />
<br />
'''Вывод:''' Поле – это единственное средство для хранения данных объекта находящегося в памяти компьютера. Поле обязательно имеет Тип и может быть либо общим для класса, создающимся в одном экземпляре, либо объектным, создающимся в каждом экземпляре объекта. В разных видах элементов программы поля имеют особенности написания и использования во время компиляции и выполнения программы.<br />
<br />
== Наследование (надо ввести понятие ниже)==<br />
Создадим классы Кошка и Собака, указав, что родителем для них является Класс Животное:<br />
<br />
'''Класс''' Кошка '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
'''Класс''' Собака '''Родитель''' Животное<br />
//тут можно определить свойства и методы работы с классом<br />
'''КонецКласса'''<br />
<br />
Теперь покажем, как можно эти классы использовать:<br />
<br />
МойКот = '''Новый''' Кот // создадим объект МойКот сложного типа - Кот<br />
ПриветЖивотное(МойКот) // передадим объект МойКот <br />
<br />
МояСобака = '''Новый''' Собака<br />
ПриветЖивотное(МояСобака)<br />
<br />
//где-то ниже определим процедуру<br />
'''Процедура''' ПриветЖивотное(МоёЖивотное '''тип''' Животное) // процедура принимает объект типа Животное<br />
'''Выбор Для''' МоёЖивотное // оператор выбора Выбор Для<br />
'''Когда''' ЭтоТип Кот<br />
'''ВыводСтроки''' "Привет кот!"<br />
'''Когда''' '''ЭтоТип''' Собака<br />
'''ВыводСтроки''' "Привет собака!"<br />
'''Иначе'''<br />
'''ВыводСтроки''' "Привет не известное животное!"<br />
'''КонецВыбора'''<br />
'''КонецПроцедуры'''<br />
<br />
Как видно из этого примера, процедура ПриветЖивотное() может приветствовать животное любого типа, даже такого, который на момент написания программы еще не существовал. Главное, чтобы не известное животное было потомком класса Животное. А вот классы Кот и Собака этой процедуре известны и приветствие выводится вполне конкретное.<br />
<br />
Таким образом, мы извлекли пользу от использования классов не имеющих ни каких свойств и методов (кроме методов родительского типа Объект). Нам пригодилась сама иерархия, согласно которой мы классифицировали объекты.<br />
<br />
Умнику на заметку: Отметьте для себя связь терминов Класс и Классификация. Вы должны выстраивать иерархию классов не как попало, а по определенным критериям, что бы можно было сказать, что вы их классифицировали.<br />
<br />
== Ссылки ==<br />
* [http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language ПРОМОКОД - официальная страница языка программирования Перфолента.NET]<br />
* [http://promcod.com.ua/Article.asp?code=20200902191745030929 ООП на Перфолента.NET часть 1. Терминология: классы, объекты и типы в языке Перфолента]<br />
* [http://promcod.com.ua/Article.asp?code=20200909140544010807 ООП на Перфолента.NET часть 2. Конструируем класс. Поля]<br />
[[Категория:Описание языка Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B_%D0%B8_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B_%D0%BD%D0%B0_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B5_%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8055Скрипты и программы на языке Перфолента.NET2020-08-05T18:07:59Z<p>Дизайнер: </p>
<hr />
<div>== Простые программы ==<br />
* [[Привет Мир (Перфолента.NET)|Привет Мир]] - простое консольное приложение<br />
== Примеры сложных программных пакетов==<br />
* [[Язык программирования Перфо (Исходный код)]] - пример реализации функционального языка программирования Перфо на Перфоленте. менее 900 строк с учётом комментариев и описания языка<br />
<br />
== См. также ==<br />
* [[Описание языка Перфолента.NET]]<br />
* [[Описание языка Перфолента.NET для программистов]]<br />
* [[Учебник по языку Перфолента.NET]]<br />
* [[Перфолента.NET]]<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Скрипты и программы на языке Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE_(%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4)&diff=8054Перфо (Исходный код)2020-08-05T18:04:01Z<p>Дизайнер: Дизайнер переименовал страницу Перфо (Исходный код) в Язык программирования Перфо (Исходный код)</p>
<hr />
<div>#перенаправление [[Язык программирования Перфо (Исходный код)]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%AF%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%9F%D0%B5%D1%80%D1%84%D0%BE_(%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4)&diff=8053Язык программирования Перфо (Исходный код)2020-08-05T18:04:00Z<p>Дизайнер: Дизайнер переименовал страницу Перфо (Исходный код) в Язык программирования Перфо (Исходный код)</p>
<hr />
<div><br />
// интерпретатор языка программирования Перфо<br />
// русскоязычный вариант языка похожего на Scheme<br />
// однако, унифицированный с языком Перфолента<br />
<br />
/*<br />
Описание языка: <br />
- есть 3 типа сущностей Идентификаторы, Значения и Списки<br />
- значениями могут быть простые типы: строки, символы, числа, даты, булево и неопределено, <br />
а так же созданные во время выполнения объекты и делегаты действий<br />
- синтаксис значений такой же, как в языке Перфолента: <br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
- любой другой набор символов не содержащий пробельных символов является идентификатором: А1, $SYM, !!!Ошибка!!!<br />
- списки состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
- действие это список, первым элементом которого является идентификатор, а остальные элементы являются параметрами действия<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
- идентификатор может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
- параметр действия может быть любой сущностью или последовательностью<br />
- последовательность это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
- оператор это специальная форма действия, в которой смысл и назначение параметров, <br />
а так же их последовательность выполнения определены стандартом языка,<br />
например, (Если (Условие) (СписокДействий1) (СписокДействий2))<br />
или (Перем ИмяПеременной Значение)<br />
Возвращаемые значения:<br />
- значение возвращает само себя<br />
- идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
- действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
- оператор возвращает то, что определено стандартом языка<br />
- последовательность возвращает результат последнего элемента<br />
<br />
*/<br />
<br />
#ТипСборки КонсольноеПриложение<br />
#ИспользоватьСтандартнуюБиблиотеку<br />
<br />
ИмпортИмён Промкод.Перфолента.Консоль<br />
<br />
//***************************<br />
&ВидноВсем<br />
Программа Перфо<br />
<br />
//стандартное окружение хранит значения и действий<br />
//заданные стандартом языка<br />
Поле СтандартноеОкружение тип клОкружение = ЗаполнитьСтандартноеОкружение()<br />
<br />
//глобальное окружение хранит значения переменных и определения действий<br />
//в глобальном контексте выполнения программы<br />
Поле ГлобОкружение тип клОкружение = Новый клОкружение(СтандартноеОкружение)<br />
<br />
//оператор (Отладка Истина) включает вывод сообщений об ошибках в консоль<br />
//при выполнении скрипта запущенного из командной строки<br />
//если отладка выключена, то консоль просто закроется и программа вернет код ошибки окружению ОС<br />
Поле Отладка тип Булево = Ложь <br />
<br />
//используем функцию Старт, а не процедуру, что бы вернуть операционной системе код возврата<br />
//---------------------------<br />
Функция Старт() тип Целое<br />
<br />
Если ЭтаПрограмма.КоличествоАргументовКоманднойСтроки > 0<br />
<br />
// выполняем скрипт из файла<br />
<br />
Файл = СокрЛП(ЭтаПрограмма.ПолучитьАргументКоманднойСтроки(0))<br />
Если ФС.ФайлСуществует(Файл) <br />
Попытка<br />
ТекстПрограммы = ФС.ПрочитатьТекст(Файл) <br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Исключение Ош<br />
Если Отладка<br />
ВыводСтроки "Ошибка выполнения программы (код 1): "+Ош.ОписаниеОшибки <br />
Пауза<br />
КонецЕсли <br />
Возврат 1 //ошибка при выполнении программы<br />
КонецПопытки<br />
Иначе<br />
Если Отладка<br />
ВыводСтроки "Ошибка (код 2): Не найден файл программы "+Файл <br />
Пауза<br />
КонецЕсли <br />
Возврат 2 //ошибка: файл программы не найден<br />
КонецЕсли<br />
Если Отладка<br />
ПереносСтроки<br />
Пауза<br />
КонецЕсли <br />
Возврат 0 //ошибок нет<br />
<br />
Иначе<br />
<br />
// интерактивная работа<br />
<br />
ВыводПС("Перфо - простой интерпретатор русского языка похожего на Scheme")<br />
Цикл<br />
ПереносСтроки<br />
Вывод("Перфо> ")<br />
ТекстПрограммы = ПрочитатьСтроку()<br />
Попытка<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Если Результат ЭтоНе Неопределено<br />
Вывод(РезультатВСтроку(Результат))<br />
КонецЕсли<br />
Исключение Ош<br />
ВыводПС("Ошибка: "+Ош.ОписаниеОшибки)<br />
КонецПопытки<br />
КонецЦикла<br />
<br />
КонецЕсли<br />
<br />
КонецФункции<br />
<br />
//запускает на выполнение текст программы с установкой переменной ЭтотОбъект<br />
//используется для запуска скрипта из других программ<br />
//---------------------------<br />
&ВидноВсем<br />
Функция ВыполнитьПрограмму(ТекстПрограммы тип Строка, ЗначениеПеременнойЭтотОбъект тип Объект = Неопределено) тип Строка <br />
Попытка<br />
ГлобОкружение.ДобавитьДействие("этотобъект", ЗначениеПеременнойЭтотОбъект)<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Возврат РезультатВСтроку(Результат)<br />
Исключение Ош<br />
Если Отладка<br />
Возврат "Ошибка: "+Ош.ОписаниеОшибки <br />
КонецЕсли <br />
Возврат Неопределено<br />
КонецПопытки<br />
КонецФункции <br />
<br />
#Область ФункцииКомпилятора<br />
<br />
//запускает на выполнение откомпилированную программу<br />
//---------------------------<br />
Функция Выполнить(СписокВыражений тип клСписок) тип Объект<br />
Результат = Неопределено<br />
Для Инд=0 По СписокВыражений.Количество-1<br />
Результат = Вычислить(СписокВыражений.ПоИндексу(Инд),ГлобОкружение) <br />
КонецЦикла<br />
Возврат Результат<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Компилировать(ТекстПрограммы тип Строка) тип Объект<br />
ПредставлениеПрограммы = Новый клСписок<br />
Спис = РазобратьНаТокены(ТекстПрограммы)<br />
Пока Спис.Количество > 0<br />
ПредставлениеПрограммы.ВКонец(ОбработатьТокены(Спис))<br />
КонецЦикла<br />
Возврат ПредставлениеПрограммы<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РазобратьНаТокены(ТекстПрограммы тип Строка) тип клСписок<br />
<br />
Пт = Новый ПостроительТекста<br />
<br />
//выделим строки, символы и даты перед тем, как разделять по пробелам<br />
//т.к. в них бывают пробелы, табуляции и т.д...<br />
ДлинаТекста=СтрДлина(ТекстПрограммы)<br />
Если ДлинаТекста<2<br />
Пт{ТекстПрограммы}<br />
Иначе<br />
масСтроки=Новый Массив<br />
Символ14=""+Символ(14)<br />
МаксЦелое=2147483647<br />
Поз1=1<br />
Цикл<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1)<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1)<br />
Если Поз2=0 и Поз3=0<br />
Пт{Сред(ТекстПрограммы,Поз1)}<br />
Прервать<br />
КонецЕсли<br />
Поз2=?(Поз2=0,МаксЦелое,Поз2)<br />
Поз3=?(Поз3=0,МаксЦелое,Поз3)<br />
Если Поз2 < Поз3 <br />
//нашли "<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз2-Поз1)}<br />
Поз1=Поз2<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1+1)<br />
~ПроверкаВторойКавычки:<br />
Если Поз2=0<br />
ВызватьИсключение "Строка не закрыта двойной кавычкой."<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если НРег(Симв)="с" или НРег(Симв)="c" //рус и англ<br />
//берем знак символа<br />
Поз2++<br />
ИначеЕсли Симв=""""<br />
//берем продолжение строки<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз2+2)<br />
Перейти ~ПроверкаВторойКавычки:<br />
ИначеЕсли Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после строки."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз2-Поз1+1))<br />
Поз1=Поз2+1<br />
КонецЕсли<br />
Иначе<br />
//нашли '<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз3-Поз1)}<br />
Поз1=Поз3<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1+1)<br />
Если Поз3=0<br />
ВызватьИсключение "Дата не закрыта одинарной кавычкой"<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после даты."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз3-Поз1+1))<br />
Поз1=Поз3+1<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЕсли<br />
ТекстПрограммы=Пт.ВСтроку<br />
<br />
//уберем комментарии и директивы препрцессора<br />
Пт = Новый ПостроительТекста<br />
Токены=ТекстПрограммы.Разделить({Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Поз=Найти(Токены[Инд],"#") <br />
Если Поз<>1<br />
Поз=Найти(Токены[Инд],"//") <br />
Если Поз>0<br />
Пт{Лев(Токены[Инд],Поз-1)}<br />
Иначе<br />
Пт{Токены[Инд]}<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
<br />
//разделим на токены<br />
Токены=Пт.ВСтроку.Заменить("("," ( ").Заменить(")"," ) ").Разделить({" ",Символы.НПП,Символы.Таб,Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Если Лев(Токены[Инд],1)=Символ14<br />
Токены[Инд]=масСтроки[Целое(Сред(Токены[Инд],2))]<br />
КонецЕсли<br />
КонецЦикла<br />
Возврат Новый клСписок(Токены) <br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОбработатьТокены(Токены тип клСписок) тип Объект<br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Неожиданный конец программы."<br />
КонецЕсли<br />
Токен = Токены.Извлечь(0)<br />
Если "(" = Токен<br />
Спис = Новый клСписок<br />
Цикл <br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Ожидается символ )."<br />
КонецЕсли<br />
Прервать Если Токены.ПоИндексу(0) = ")"<br />
Спис.ВКонец(ОбработатьТокены(Токены))<br />
КонецЦикла<br />
Токены.Извлечь(0) //убираем )<br />
Возврат Спис<br />
ИначеЕсли ")" = Токен<br />
ВызватьИсключение "Неожиданный символ )."<br />
Иначе<br />
Возврат Атом(Токен)<br />
КонецЕсли<br />
КонецФункции <br />
<br />
//---------------------------<br />
// Распознаёт неопределено, числа, строки, символы, булево, даты и идентификаторы<br />
Функция Атом(Токен тип Строка) тип Объект <br />
Если НРег(Токен)="неопределено"<br />
//это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("""") и Токен.ЗаканчиваетсяНа("""")<br />
//это строка<br />
Возврат Токен.Сред(2,СтрДлина(Токен)-2)<br />
КонецЕсли <br />
Если СтрДлина(Токен)=4 и Токен.НачинаетсяС("""") и (Токен.ЗаканчиваетсяНа("""с") или Токен.ЗаканчиваетсяНа("""c")) //рус и англ<br />
//это символ<br />
Возврат Символ(Токен.Сред(2,1))<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("'") и Токен.ЗаканчиваетсяНа("'")<br />
Попытка<br />
//это дата<br />
Возврат Дата(Токен.Сред(2,СтрДлина(Токен)-2))<br />
КонецПопытки<br />
КонецЕсли <br />
Бул=Ложь<br />
Чис=0ч<br />
//числа записываются через точку, но и через запятую сработает<br />
Если РаспознатьЧисло(СтрЗаменить(Токен,".",Сред(Строка(1.1),2,1)),Чис)<br />
//это число<br />
Возврат Чис<br />
ИначеЕсли РаспознатьБулево(Токен,Бул)<br />
//это булево<br />
Возврат Бул<br />
КонецЕсли<br />
//это какой-то идентификатор<br />
Возврат Новый клИдентификатор(Токен)<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РезультатВСтроку(Результат тип Объект) тип Строка <br />
Если Результат Это Неопределено<br />
Возврат ""<br />
ИначеЕсли Результат ЭтоТип клСписок Для Спис<br />
Стр = "("<br />
Для Об Из Спис.Данные<br />
Стр &= ?(Стр = "(",""," ")+РезультатВСтроку(Об)<br />
КонецЦикла<br />
Возврат Стр+")"<br />
Иначе<br />
Возврат Строка(Результат)<br />
КонецЕсли <br />
КонецФункции <br />
<br />
//тут можно определить стандартные функции и значения языка<br />
//все эти значения переопределяемые во время выполнения<br />
//---------------------------<br />
Функция ЗаполнитьСтандартноеОкружение() тип клОкружение <br />
Окруж = Новый клОкружение()<br />
Окруж.ДобавитьДействие{<br />
{"вкпс", Символы.ВКПС}, <br />
{"вк", Символы.ВК}, <br />
{"пс", Символы.ПС}, <br />
{"таб", Символы.Таб}, <br />
{"нпп", Символы.НПП}, <br />
{"упс", Символы.УПС},<br />
<br />
{"+", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"-", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"*", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"/", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"^", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"**", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"макс", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"мин", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
<br />
{">", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{">=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<>", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
{"!=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
<br />
{"помодулю", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"корень", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"синус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"косинус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")}<br />
<br />
//{"append", op.add}, <br />
//{"apply", apply},<br />
//{"begin", lambda *x: x[-1]},<br />
//{"car", lambda x: x[0]},<br />
//{"cdr", lambda x: x[1:]}, <br />
//{"cons", lambda x,y: [x] + y},<br />
//{"eq?", op.is_}, <br />
//{"equal?", op.eq}, <br />
//{"length", len}, <br />
//{"list", lambda *x: list(x)}, <br />
//{"list?", lambda x: isinstance(x,list)}, <br />
//{"map", map},<br />
//{"not", op.not_},<br />
//{"null?", lambda x: x == []}, <br />
//{"number?", lambda x: isinstance(x, Number)}, <br />
//{"procedure?", callable},<br />
//{"round", round,<br />
//{"symbol?", lambda x: isinstance(x, Symbol)}<br />
}<br />
Возврат Окруж<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Вычислить(Элемент тип Объект, Окруж тип клОкружение) тип Объект<br />
<br />
Если Элемент ЭтоТип клИдентификатор Для ТекИдентификатор <br />
//получим значение переменной<br />
ТекОкруж = Окруж.НайтиОкружение(ТекИдентификатор)<br />
Если ТекОкруж Это Неопределено<br />
ВызватьИсключение "Не найден идентификатор "+ТекИдентификатор <br />
Иначе<br />
Возврат ТекОкруж.ПолучитьДействие(ТекИдентификатор)<br />
КонецЕсли<br />
КонецЕсли<br />
Если Элемент ЭтоНеТип клСписок <br />
//возвращаем атом<br />
Возврат Элемент <br />
КонецЕсли<br />
<br />
//это точно список<br />
<br />
//?????? РУГАЕТСЯ<br />
//Спис = Элемент КАК клСписок<br />
<br />
Спис = ТипКТипу(Элемент,"клСписок")<br />
Если Спис.Количество=0<br />
Возврат Неопределено <br />
КонецЕсли<br />
Перем ИД тип Строка = ""<br />
Если Спис.ПоИндексу(0) ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
Рез = Вычислить(Спис.ПоИндексу(0), Окруж)<br />
Если Рез ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//все-таки первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
//обходим последовательность<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Рез=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат Рез<br />
КонецЕсли<br />
КонецЕсли<br />
<br />
Если ИД = "пауза"<br />
//выводим в консоль сообщение и ждем нажатия любой клавиши<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Пауза не имеет операндов." <br />
КонецЕсли<br />
Пауза<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "очистить"<br />
//очищаем экран консоли<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Очистить не имеет операндов." <br />
КонецЕсли<br />
Очистить<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "отладка"<br />
//включаем/выключаем режим отладки скрипта<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Отладка." <br />
КонецЕсли<br />
Отладка=Булево(Вычислить(Спис.ПоИндексу(1), Окруж))<br />
Возврат Отладка<br />
<br />
ИначеЕсли ИД = "ввод" <br />
//вычисляем и выводим в консоль все приглашения<br />
//и ждем ввода строки в консоль и нажатия клавиши Ввод (Enter)<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат ПрочитатьСтроку()<br />
<br />
ИначеЕсли ИД = "вывод" <br />
//вычисляем и выводим в консоль все элементы списка<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "идент"<br />
//вычисляем операнд и превращаем результат в идентификатор<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Идент." <br />
КонецЕсли<br />
Возврат Новый клИдентификатор(РезультатВСтроку(Вычислить(Спис.ПоИндексу(1), Окруж)))<br />
<br />
ИначеЕсли ИД = "если" <br />
//вычисляем условие<br />
//если условие выполнилось, то вычисляем Список1<br />
//иначе, вычисляем Список2<br />
//возвращаем результат того списка, который вычислялся<br />
//(Если (Условие) Список1 Список2)<br />
Если Спис.Количество<>4<br />
ВызватьИсключение "Не верное число операндов в операторе ?." <br />
КонецЕсли<br />
Возврат Вычислить(?(Булево(Вычислить(Спис.ПоИндексу(1), Окруж)),Спис.ПоИндексу(2),Спис.ПоИндексу(3)), Окруж)<br />
<br />
ИначеЕсли ИД = "новый" <br />
//создать новый объект .Net из загруженных сборок <br />
//пространство имён Промкод.Перфолента импортировано по умолчанию<br />
//например, (Новый Массив) или (Новый Структура "Вид,Количество", "Простой", 5)<br />
Если Спис.Количество<2<br />
ВызватьИсключение "Не верное число операндов в операторе Новый." <br />
КонецЕсли<br />
//идентификатор типа объекта может вычисляться налету <br />
//например, (Новый (Идент (+ "Мас" "сив")))<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Новый не является идентификатором." <br />
КонецЕсли<br />
ТипОбъекта = НайтиТипОбъекта(Рез)<br />
Кво=Спис.Количество<br />
Массив Парамс[Кво-3] тип Объект<br />
Для Инд=2 По Кво-1<br />
Парамс[Инд-2]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат System.Activator.CreateInstance(ТипОбъекта,Парамс)<br />
<br />
ИначеЕсли ИД = "перем" <br />
//определяем переменную<br />
//например, присвоим переменной А1 значение 100: (Перем А1 100)<br />
//переменная сохраняется в текущее окружение<br />
Если Спис.Количество<>3<br />
ВызватьИсключение "Не верное число операндов в операторе Перем." <br />
КонецЕсли<br />
//идентификатор переменной может вычисляться налету <br />
//например, (Перем (Идент (+ "А" "1")) 100)<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Перем не является идентификатором." <br />
КонецЕсли<br />
Зн = Вычислить(Спис.ПоИндексу(2), Окруж)<br />
Окруж.ВставитьДействие(Рез, Зн)<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "функ" <br />
//определение анонимной функции (Функ (ИдентификаторыПараметров...) ТелоФункции)<br />
//анонимная функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Имя параметра № "+(Инд+1)+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЦикла<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
Возврат Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
ИначеЕсли ИД = "функция" <br />
//определение функции (Функция (ИмяФункции ИдентификаторыПараметров...) ТелоФункции)<br />
//функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
Перем ИмяФункции тип Строка = Неопределено<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Если Инд=0<br />
ВызватьИсключение "Имя Функции не является идентификатором." <br />
Иначе<br />
ВызватьИсключение "Имя параметра № "+Инд+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
КонецЕсли<br />
Если Инд=0<br />
ИмяФункции = Рез<br />
Иначе<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЕсли<br />
КонецЦикла<br />
Если ИмяФункции = Неопределено<br />
ВызватьИсключение "Имя функции неопределено." <br />
КонецЕсли<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
ФункП = Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Окруж.ВставитьДействие(ИмяФункции, ФункП)<br />
Возврат Неопределено<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
Иначе <br />
//(Действие Параметры...)<br />
//остался только один вариант<br />
//надо выполнить действие из окружения<br />
Действие = Вычислить(ТекИдентификатор, Окруж)<br />
Кво=Спис.Количество<br />
Массив Элементы[Кво-2] тип Объект<br />
Для Инд=1 По Кво-1<br />
Элементы[Инд-1]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат ВыполнитьДействие(Действие, ИД, Элементы, Окруж)<br />
КонецЕсли<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ВыполнитьДействие(Действие тип Объект, ИД тип Строка, Аргументы тип Объект[], Окруж тип клОкружение) тип Объект<br />
Если Действие ЭтоТип ФункцияСМассивомОперандов Для ФСМО<br />
Возврат ФСМО.Invoke(ИД,Объект(Аргументы))<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСОднимОперандом Для ФСОО<br />
Возврат ФСОО.Invoke(ИД,Аргументы[0])<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСДвумяОперандами Для ФСДО<br />
Возврат ФСДО.Invoke(ИД,Аргументы[0],Аргументы[1])<br />
<br />
ИначеЕсли Действие ЭтоТип клФункцияПользователя Для ФПЛЗ<br />
<br />
ОкружФункции = Новый клОкружение(ФПЛЗ.ИдентификаторыПараметров,Аргументы,ФПЛЗ.Окружение)<br />
Возврат Вычислить(ФПЛЗ.ТелоФункции,ОкружФункции)<br />
<br />
//??????? ИначеЕсли Действие ЭтоТип Тип("System.Delegate") Для ФСД<br />
//ошибка на слове Для<br />
<br />
ИначеЕсли Действие ЭтоТип System.Delegate Для ФСД<br />
Возврат ФСД.DynamicInvoke(Аргументы)<br />
<br />
ИначеЕсли Найти(ИД,".")>0<br />
//вызов метода объекта<br />
<br />
<br />
ИначеЕсли Аргументы.Количество>0<br />
ВызватьИсключение "Значение вызывается как действие."<br />
<br />
Иначе<br />
//просто значение<br />
Возврат Действие<br />
КонецЕсли<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
#Область ВстроенныеФункцииЯзыка<br />
<br />
//---------------------------<br />
Функция ОператорСМассивомОперандов(ИмяФункции тип Строка, Парам Операнды тип Объект[]) тип Объект <br />
Если Операнды Это Неопределено<br />
Возврат 0<br />
КонецЕсли<br />
Если Операнды.Количество=0<br />
ВызватьИсключение "Не достаточно операндов в Функции "+ИмяФункции+"."<br />
КонецЕсли<br />
Перем Рез тип Объект = Операнды[0]<br />
Для Инд=1 По Операнды.Количество-1<br />
Выбор Для НРег(ИмяФункции)<br />
Когда "+" Тогда <br />
Рез += Операнды[Инд]<br />
Когда "-" Тогда <br />
Рез -= Операнды[Инд]<br />
Когда "*" Тогда <br />
Рез *= Операнды[Инд]<br />
Когда "/" Тогда <br />
Рез /= Операнды[Инд]<br />
Когда "^","**" Тогда <br />
Рез ^= Операнды[Инд]<br />
Когда "макс" Тогда <br />
Если Операнды[Инд] > Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Когда "мин" Тогда <br />
Если Операнды[Инд] < Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецЦикла<br />
Возврат Рез<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда "помодулю" Тогда <br />
Возврат Математика.ПоМодулю(Число(Операнд))<br />
Когда "синус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "косинус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "корень" Тогда <br />
Возврат Число(Математика.Корень(ДВещ(Операнд)))<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда ">" Тогда <br />
Возврат Операнд1 > Операнд2<br />
Когда "<" Тогда <br />
Возврат Операнд1 < Операнд2<br />
Когда ">=" Тогда <br />
Возврат Операнд1 >= Операнд2<br />
Когда "<=" Тогда <br />
Возврат Операнд1 <= Операнд2<br />
Когда "=" Тогда <br />
Возврат Операнд1 = Операнд2<br />
Когда "<>", "!=" Тогда <br />
Возврат Операнд1 <> Операнд2<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
//---------------------------<br />
Функция НайтиТипОбъекта(ИД тип Строка) тип Тип <br />
ИмпортИмён System<br />
ИмпортИмён System.Reflection<br />
Перем НашлиТип тип Тип = Неопределено<br />
//ищем в загруженных сборках <br />
Для Ассм тип Assembly Из AppDomain.CurrentDomain.GetAssemblies<br />
Для СИД тип Строка Из {ИД,"Промкод.Перфолента."+ИД}<br />
тп = Ассм.GetType(СИД, Ложь, Истина)<br />
Если тп ЭтоНе Неопределено<br />
Если НашлиТип Это Неопределено<br />
НашлиТип=тп<br />
Прервать<br />
Иначе<br />
ВызватьИсключение "Указанный тип "+ИД+" существует в нескольких загруженных сборках."<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЦикла<br />
Если НашлиТип Это Неопределено<br />
ВызватьИсключение "Указанный тип "+ИД+" НЕ найден в загруженных сборках."<br />
КонецЕсли<br />
Возврат НашлиТип<br />
КонецФункции <br />
<br />
КонецПрограммы <br />
<br />
//==========================================================================================<br />
#Область ВспомогательныеКлассы<br />
<br />
Делегат Функция ФункцияСМассивомОперандов(ИмяФункции тип Строка, Операнды тип Объект[]) тип Объект <br />
Делегат Функция ФункцияСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект<br />
Делегат Функция ФункцияСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект<br />
<br />
//окружение хранит список действий и переменных<br />
//***************************<br />
Класс клОкружение <br />
Поле _Окружение тип Структура = Новый Структура<br />
Поле _ВнешнееОкружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(ВнешнееОкружение тип клОкружение = Неопределено)<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип Строка[], Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип клСписок, Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ДобавитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Добавить(НРег(Идентификатор),Действие)<br />
КонецПроцедуры<br />
//---------------------------<br />
&ВидноВсем <br />
Функция НайтиОкружение(Идентификатор тип Строка) тип клОкружение<br />
Если _Окружение.СодержитКлюч(НРег(Идентификатор)) Тогда<br />
Возврат ЭтотОбъект<br />
ИначеЕсли _ВнешнееОкружение Это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли<br />
Возврат _ВнешнееОкружение.НайтиОкружение(Идентификатор)<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Функция ПолучитьДействие(Идентификатор тип Строка) тип Объект<br />
Возврат _Окружение.Получить(НРег(Идентификатор))<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ВставитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Вставить(НРег(Идентификатор), Действие)<br />
КонецПроцедуры <br />
КонецКласса<br />
<br />
//функция определяемая пользователем<br />
//***************************<br />
Класс клФункцияПользователя<br />
&ВидноВсем <br />
Поле ИдентификаторыПараметров тип клСписок<br />
&ВидноВсем <br />
Поле ТелоФункции тип Объект<br />
&ВидноВсем <br />
Поле Окружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(пИдентификаторыПараметров тип клСписок, пТелоФункции тип Объект, пОкруж тип клОкружение)<br />
Присвоить ИдентификаторыПараметров, ТелоФункции, Окружение = пИдентификаторыПараметров, пТелоФункции, пОкруж<br />
КонецКонструктора<br />
КонецКласса<br />
<br />
//список хранит элементы находящиеся в круглых скобках<br />
//***************************<br />
Класс клСписок <br />
<br />
&ВидноВсем <br />
Поле Данные тип Массив = Новый Массив<br />
<br />
&ВидноВсем <br />
Конструктор() <br />
КонецКонструктора <br />
<br />
&ВидноВсем <br />
Конструктор(МассивСтрок тип Строка[]) <br />
Данные.ДобавитьВсе(МассивСтрок)<br />
КонецКонструктора <br />
<br />
&ВидноВсем<br />
Процедура ВКонец(Значение тип Объект)<br />
Данные.Добавить(Значение) <br />
КонецПроцедуры<br />
<br />
&ВидноВсем<br />
Функция ПоИндексу(Индекс тип Целое) тип Объект <br />
Возврат Данные.Получить(Индекс)<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Извлечь(Индекс тип Целое) тип Объект <br />
Элемент = Данные.Получить(Индекс)<br />
Данные.Удалить(Индекс)<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Количество() тип Целое <br />
Возврат Данные.Количество<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
//идентификатор хранит имя действия <br />
//***************************<br />
Класс клИдентификатор<br />
<br />
Поле _ИД тип Строка <br />
<br />
&ВидноВсем <br />
Конструктор(ИД тип Строка) <br />
_ИД=ИД<br />
КонецКонструктора <br />
<br />
//переопределим функцию преобразования к строке<br />
&ВидноВсем, Переопределение<br />
Функция ToString() тип Строка <br />
Возврат _ИД<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
#КонецОбласти <br />
<br />
== См. также ==<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Скрипты и программы на языке Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%AF%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%9F%D0%B5%D1%80%D1%84%D0%BE_(%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4)&diff=8052Язык программирования Перфо (Исходный код)2020-08-05T18:02:58Z<p>Дизайнер: </p>
<hr />
<div><br />
// интерпретатор языка программирования Перфо<br />
// русскоязычный вариант языка похожего на Scheme<br />
// однако, унифицированный с языком Перфолента<br />
<br />
/*<br />
Описание языка: <br />
- есть 3 типа сущностей Идентификаторы, Значения и Списки<br />
- значениями могут быть простые типы: строки, символы, числа, даты, булево и неопределено, <br />
а так же созданные во время выполнения объекты и делегаты действий<br />
- синтаксис значений такой же, как в языке Перфолента: <br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
- любой другой набор символов не содержащий пробельных символов является идентификатором: А1, $SYM, !!!Ошибка!!!<br />
- списки состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
- действие это список, первым элементом которого является идентификатор, а остальные элементы являются параметрами действия<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
- идентификатор может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
- параметр действия может быть любой сущностью или последовательностью<br />
- последовательность это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
- оператор это специальная форма действия, в которой смысл и назначение параметров, <br />
а так же их последовательность выполнения определены стандартом языка,<br />
например, (Если (Условие) (СписокДействий1) (СписокДействий2))<br />
или (Перем ИмяПеременной Значение)<br />
Возвращаемые значения:<br />
- значение возвращает само себя<br />
- идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
- действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
- оператор возвращает то, что определено стандартом языка<br />
- последовательность возвращает результат последнего элемента<br />
<br />
*/<br />
<br />
#ТипСборки КонсольноеПриложение<br />
#ИспользоватьСтандартнуюБиблиотеку<br />
<br />
ИмпортИмён Промкод.Перфолента.Консоль<br />
<br />
//***************************<br />
&ВидноВсем<br />
Программа Перфо<br />
<br />
//стандартное окружение хранит значения и действий<br />
//заданные стандартом языка<br />
Поле СтандартноеОкружение тип клОкружение = ЗаполнитьСтандартноеОкружение()<br />
<br />
//глобальное окружение хранит значения переменных и определения действий<br />
//в глобальном контексте выполнения программы<br />
Поле ГлобОкружение тип клОкружение = Новый клОкружение(СтандартноеОкружение)<br />
<br />
//оператор (Отладка Истина) включает вывод сообщений об ошибках в консоль<br />
//при выполнении скрипта запущенного из командной строки<br />
//если отладка выключена, то консоль просто закроется и программа вернет код ошибки окружению ОС<br />
Поле Отладка тип Булево = Ложь <br />
<br />
//используем функцию Старт, а не процедуру, что бы вернуть операционной системе код возврата<br />
//---------------------------<br />
Функция Старт() тип Целое<br />
<br />
Если ЭтаПрограмма.КоличествоАргументовКоманднойСтроки > 0<br />
<br />
// выполняем скрипт из файла<br />
<br />
Файл = СокрЛП(ЭтаПрограмма.ПолучитьАргументКоманднойСтроки(0))<br />
Если ФС.ФайлСуществует(Файл) <br />
Попытка<br />
ТекстПрограммы = ФС.ПрочитатьТекст(Файл) <br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Исключение Ош<br />
Если Отладка<br />
ВыводСтроки "Ошибка выполнения программы (код 1): "+Ош.ОписаниеОшибки <br />
Пауза<br />
КонецЕсли <br />
Возврат 1 //ошибка при выполнении программы<br />
КонецПопытки<br />
Иначе<br />
Если Отладка<br />
ВыводСтроки "Ошибка (код 2): Не найден файл программы "+Файл <br />
Пауза<br />
КонецЕсли <br />
Возврат 2 //ошибка: файл программы не найден<br />
КонецЕсли<br />
Если Отладка<br />
ПереносСтроки<br />
Пауза<br />
КонецЕсли <br />
Возврат 0 //ошибок нет<br />
<br />
Иначе<br />
<br />
// интерактивная работа<br />
<br />
ВыводПС("Перфо - простой интерпретатор русского языка похожего на Scheme")<br />
Цикл<br />
ПереносСтроки<br />
Вывод("Перфо> ")<br />
ТекстПрограммы = ПрочитатьСтроку()<br />
Попытка<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Если Результат ЭтоНе Неопределено<br />
Вывод(РезультатВСтроку(Результат))<br />
КонецЕсли<br />
Исключение Ош<br />
ВыводПС("Ошибка: "+Ош.ОписаниеОшибки)<br />
КонецПопытки<br />
КонецЦикла<br />
<br />
КонецЕсли<br />
<br />
КонецФункции<br />
<br />
//запускает на выполнение текст программы с установкой переменной ЭтотОбъект<br />
//используется для запуска скрипта из других программ<br />
//---------------------------<br />
&ВидноВсем<br />
Функция ВыполнитьПрограмму(ТекстПрограммы тип Строка, ЗначениеПеременнойЭтотОбъект тип Объект = Неопределено) тип Строка <br />
Попытка<br />
ГлобОкружение.ДобавитьДействие("этотобъект", ЗначениеПеременнойЭтотОбъект)<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Возврат РезультатВСтроку(Результат)<br />
Исключение Ош<br />
Если Отладка<br />
Возврат "Ошибка: "+Ош.ОписаниеОшибки <br />
КонецЕсли <br />
Возврат Неопределено<br />
КонецПопытки<br />
КонецФункции <br />
<br />
#Область ФункцииКомпилятора<br />
<br />
//запускает на выполнение откомпилированную программу<br />
//---------------------------<br />
Функция Выполнить(СписокВыражений тип клСписок) тип Объект<br />
Результат = Неопределено<br />
Для Инд=0 По СписокВыражений.Количество-1<br />
Результат = Вычислить(СписокВыражений.ПоИндексу(Инд),ГлобОкружение) <br />
КонецЦикла<br />
Возврат Результат<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Компилировать(ТекстПрограммы тип Строка) тип Объект<br />
ПредставлениеПрограммы = Новый клСписок<br />
Спис = РазобратьНаТокены(ТекстПрограммы)<br />
Пока Спис.Количество > 0<br />
ПредставлениеПрограммы.ВКонец(ОбработатьТокены(Спис))<br />
КонецЦикла<br />
Возврат ПредставлениеПрограммы<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РазобратьНаТокены(ТекстПрограммы тип Строка) тип клСписок<br />
<br />
Пт = Новый ПостроительТекста<br />
<br />
//выделим строки, символы и даты перед тем, как разделять по пробелам<br />
//т.к. в них бывают пробелы, табуляции и т.д...<br />
ДлинаТекста=СтрДлина(ТекстПрограммы)<br />
Если ДлинаТекста<2<br />
Пт{ТекстПрограммы}<br />
Иначе<br />
масСтроки=Новый Массив<br />
Символ14=""+Символ(14)<br />
МаксЦелое=2147483647<br />
Поз1=1<br />
Цикл<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1)<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1)<br />
Если Поз2=0 и Поз3=0<br />
Пт{Сред(ТекстПрограммы,Поз1)}<br />
Прервать<br />
КонецЕсли<br />
Поз2=?(Поз2=0,МаксЦелое,Поз2)<br />
Поз3=?(Поз3=0,МаксЦелое,Поз3)<br />
Если Поз2 < Поз3 <br />
//нашли "<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз2-Поз1)}<br />
Поз1=Поз2<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1+1)<br />
~ПроверкаВторойКавычки:<br />
Если Поз2=0<br />
ВызватьИсключение "Строка не закрыта двойной кавычкой."<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если НРег(Симв)="с" или НРег(Симв)="c" //рус и англ<br />
//берем знак символа<br />
Поз2++<br />
ИначеЕсли Симв=""""<br />
//берем продолжение строки<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз2+2)<br />
Перейти ~ПроверкаВторойКавычки:<br />
ИначеЕсли Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после строки."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз2-Поз1+1))<br />
Поз1=Поз2+1<br />
КонецЕсли<br />
Иначе<br />
//нашли '<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз3-Поз1)}<br />
Поз1=Поз3<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1+1)<br />
Если Поз3=0<br />
ВызватьИсключение "Дата не закрыта одинарной кавычкой"<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после даты."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз3-Поз1+1))<br />
Поз1=Поз3+1<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЕсли<br />
ТекстПрограммы=Пт.ВСтроку<br />
<br />
//уберем комментарии и директивы препрцессора<br />
Пт = Новый ПостроительТекста<br />
Токены=ТекстПрограммы.Разделить({Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Поз=Найти(Токены[Инд],"#") <br />
Если Поз<>1<br />
Поз=Найти(Токены[Инд],"//") <br />
Если Поз>0<br />
Пт{Лев(Токены[Инд],Поз-1)}<br />
Иначе<br />
Пт{Токены[Инд]}<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
<br />
//разделим на токены<br />
Токены=Пт.ВСтроку.Заменить("("," ( ").Заменить(")"," ) ").Разделить({" ",Символы.НПП,Символы.Таб,Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Если Лев(Токены[Инд],1)=Символ14<br />
Токены[Инд]=масСтроки[Целое(Сред(Токены[Инд],2))]<br />
КонецЕсли<br />
КонецЦикла<br />
Возврат Новый клСписок(Токены) <br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОбработатьТокены(Токены тип клСписок) тип Объект<br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Неожиданный конец программы."<br />
КонецЕсли<br />
Токен = Токены.Извлечь(0)<br />
Если "(" = Токен<br />
Спис = Новый клСписок<br />
Цикл <br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Ожидается символ )."<br />
КонецЕсли<br />
Прервать Если Токены.ПоИндексу(0) = ")"<br />
Спис.ВКонец(ОбработатьТокены(Токены))<br />
КонецЦикла<br />
Токены.Извлечь(0) //убираем )<br />
Возврат Спис<br />
ИначеЕсли ")" = Токен<br />
ВызватьИсключение "Неожиданный символ )."<br />
Иначе<br />
Возврат Атом(Токен)<br />
КонецЕсли<br />
КонецФункции <br />
<br />
//---------------------------<br />
// Распознаёт неопределено, числа, строки, символы, булево, даты и идентификаторы<br />
Функция Атом(Токен тип Строка) тип Объект <br />
Если НРег(Токен)="неопределено"<br />
//это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("""") и Токен.ЗаканчиваетсяНа("""")<br />
//это строка<br />
Возврат Токен.Сред(2,СтрДлина(Токен)-2)<br />
КонецЕсли <br />
Если СтрДлина(Токен)=4 и Токен.НачинаетсяС("""") и (Токен.ЗаканчиваетсяНа("""с") или Токен.ЗаканчиваетсяНа("""c")) //рус и англ<br />
//это символ<br />
Возврат Символ(Токен.Сред(2,1))<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("'") и Токен.ЗаканчиваетсяНа("'")<br />
Попытка<br />
//это дата<br />
Возврат Дата(Токен.Сред(2,СтрДлина(Токен)-2))<br />
КонецПопытки<br />
КонецЕсли <br />
Бул=Ложь<br />
Чис=0ч<br />
//числа записываются через точку, но и через запятую сработает<br />
Если РаспознатьЧисло(СтрЗаменить(Токен,".",Сред(Строка(1.1),2,1)),Чис)<br />
//это число<br />
Возврат Чис<br />
ИначеЕсли РаспознатьБулево(Токен,Бул)<br />
//это булево<br />
Возврат Бул<br />
КонецЕсли<br />
//это какой-то идентификатор<br />
Возврат Новый клИдентификатор(Токен)<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РезультатВСтроку(Результат тип Объект) тип Строка <br />
Если Результат Это Неопределено<br />
Возврат ""<br />
ИначеЕсли Результат ЭтоТип клСписок Для Спис<br />
Стр = "("<br />
Для Об Из Спис.Данные<br />
Стр &= ?(Стр = "(",""," ")+РезультатВСтроку(Об)<br />
КонецЦикла<br />
Возврат Стр+")"<br />
Иначе<br />
Возврат Строка(Результат)<br />
КонецЕсли <br />
КонецФункции <br />
<br />
//тут можно определить стандартные функции и значения языка<br />
//все эти значения переопределяемые во время выполнения<br />
//---------------------------<br />
Функция ЗаполнитьСтандартноеОкружение() тип клОкружение <br />
Окруж = Новый клОкружение()<br />
Окруж.ДобавитьДействие{<br />
{"вкпс", Символы.ВКПС}, <br />
{"вк", Символы.ВК}, <br />
{"пс", Символы.ПС}, <br />
{"таб", Символы.Таб}, <br />
{"нпп", Символы.НПП}, <br />
{"упс", Символы.УПС},<br />
<br />
{"+", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"-", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"*", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"/", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"^", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"**", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"макс", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"мин", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
<br />
{">", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{">=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<>", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
{"!=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
<br />
{"помодулю", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"корень", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"синус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"косинус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")}<br />
<br />
//{"append", op.add}, <br />
//{"apply", apply},<br />
//{"begin", lambda *x: x[-1]},<br />
//{"car", lambda x: x[0]},<br />
//{"cdr", lambda x: x[1:]}, <br />
//{"cons", lambda x,y: [x] + y},<br />
//{"eq?", op.is_}, <br />
//{"equal?", op.eq}, <br />
//{"length", len}, <br />
//{"list", lambda *x: list(x)}, <br />
//{"list?", lambda x: isinstance(x,list)}, <br />
//{"map", map},<br />
//{"not", op.not_},<br />
//{"null?", lambda x: x == []}, <br />
//{"number?", lambda x: isinstance(x, Number)}, <br />
//{"procedure?", callable},<br />
//{"round", round,<br />
//{"symbol?", lambda x: isinstance(x, Symbol)}<br />
}<br />
Возврат Окруж<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Вычислить(Элемент тип Объект, Окруж тип клОкружение) тип Объект<br />
<br />
Если Элемент ЭтоТип клИдентификатор Для ТекИдентификатор <br />
//получим значение переменной<br />
ТекОкруж = Окруж.НайтиОкружение(ТекИдентификатор)<br />
Если ТекОкруж Это Неопределено<br />
ВызватьИсключение "Не найден идентификатор "+ТекИдентификатор <br />
Иначе<br />
Возврат ТекОкруж.ПолучитьДействие(ТекИдентификатор)<br />
КонецЕсли<br />
КонецЕсли<br />
Если Элемент ЭтоНеТип клСписок <br />
//возвращаем атом<br />
Возврат Элемент <br />
КонецЕсли<br />
<br />
//это точно список<br />
<br />
//?????? РУГАЕТСЯ<br />
//Спис = Элемент КАК клСписок<br />
<br />
Спис = ТипКТипу(Элемент,"клСписок")<br />
Если Спис.Количество=0<br />
Возврат Неопределено <br />
КонецЕсли<br />
Перем ИД тип Строка = ""<br />
Если Спис.ПоИндексу(0) ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
Рез = Вычислить(Спис.ПоИндексу(0), Окруж)<br />
Если Рез ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//все-таки первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
//обходим последовательность<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Рез=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат Рез<br />
КонецЕсли<br />
КонецЕсли<br />
<br />
Если ИД = "пауза"<br />
//выводим в консоль сообщение и ждем нажатия любой клавиши<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Пауза не имеет операндов." <br />
КонецЕсли<br />
Пауза<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "очистить"<br />
//очищаем экран консоли<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Очистить не имеет операндов." <br />
КонецЕсли<br />
Очистить<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "отладка"<br />
//включаем/выключаем режим отладки скрипта<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Отладка." <br />
КонецЕсли<br />
Отладка=Булево(Вычислить(Спис.ПоИндексу(1), Окруж))<br />
Возврат Отладка<br />
<br />
ИначеЕсли ИД = "ввод" <br />
//вычисляем и выводим в консоль все приглашения<br />
//и ждем ввода строки в консоль и нажатия клавиши Ввод (Enter)<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат ПрочитатьСтроку()<br />
<br />
ИначеЕсли ИД = "вывод" <br />
//вычисляем и выводим в консоль все элементы списка<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "идент"<br />
//вычисляем операнд и превращаем результат в идентификатор<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Идент." <br />
КонецЕсли<br />
Возврат Новый клИдентификатор(РезультатВСтроку(Вычислить(Спис.ПоИндексу(1), Окруж)))<br />
<br />
ИначеЕсли ИД = "если" <br />
//вычисляем условие<br />
//если условие выполнилось, то вычисляем Список1<br />
//иначе, вычисляем Список2<br />
//возвращаем результат того списка, который вычислялся<br />
//(Если (Условие) Список1 Список2)<br />
Если Спис.Количество<>4<br />
ВызватьИсключение "Не верное число операндов в операторе ?." <br />
КонецЕсли<br />
Возврат Вычислить(?(Булево(Вычислить(Спис.ПоИндексу(1), Окруж)),Спис.ПоИндексу(2),Спис.ПоИндексу(3)), Окруж)<br />
<br />
ИначеЕсли ИД = "новый" <br />
//создать новый объект .Net из загруженных сборок <br />
//пространство имён Промкод.Перфолента импортировано по умолчанию<br />
//например, (Новый Массив) или (Новый Структура "Вид,Количество", "Простой", 5)<br />
Если Спис.Количество<2<br />
ВызватьИсключение "Не верное число операндов в операторе Новый." <br />
КонецЕсли<br />
//идентификатор типа объекта может вычисляться налету <br />
//например, (Новый (Идент (+ "Мас" "сив")))<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Новый не является идентификатором." <br />
КонецЕсли<br />
ТипОбъекта = НайтиТипОбъекта(Рез)<br />
Кво=Спис.Количество<br />
Массив Парамс[Кво-3] тип Объект<br />
Для Инд=2 По Кво-1<br />
Парамс[Инд-2]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат System.Activator.CreateInstance(ТипОбъекта,Парамс)<br />
<br />
ИначеЕсли ИД = "перем" <br />
//определяем переменную<br />
//например, присвоим переменной А1 значение 100: (Перем А1 100)<br />
//переменная сохраняется в текущее окружение<br />
Если Спис.Количество<>3<br />
ВызватьИсключение "Не верное число операндов в операторе Перем." <br />
КонецЕсли<br />
//идентификатор переменной может вычисляться налету <br />
//например, (Перем (Идент (+ "А" "1")) 100)<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Перем не является идентификатором." <br />
КонецЕсли<br />
Зн = Вычислить(Спис.ПоИндексу(2), Окруж)<br />
Окруж.ВставитьДействие(Рез, Зн)<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "функ" <br />
//определение анонимной функции (Функ (ИдентификаторыПараметров...) ТелоФункции)<br />
//анонимная функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Имя параметра № "+(Инд+1)+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЦикла<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
Возврат Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
ИначеЕсли ИД = "функция" <br />
//определение функции (Функция (ИмяФункции ИдентификаторыПараметров...) ТелоФункции)<br />
//функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
Перем ИмяФункции тип Строка = Неопределено<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Если Инд=0<br />
ВызватьИсключение "Имя Функции не является идентификатором." <br />
Иначе<br />
ВызватьИсключение "Имя параметра № "+Инд+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
КонецЕсли<br />
Если Инд=0<br />
ИмяФункции = Рез<br />
Иначе<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЕсли<br />
КонецЦикла<br />
Если ИмяФункции = Неопределено<br />
ВызватьИсключение "Имя функции неопределено." <br />
КонецЕсли<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
ФункП = Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Окруж.ВставитьДействие(ИмяФункции, ФункП)<br />
Возврат Неопределено<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
Иначе <br />
//(Действие Параметры...)<br />
//остался только один вариант<br />
//надо выполнить действие из окружения<br />
Действие = Вычислить(ТекИдентификатор, Окруж)<br />
Кво=Спис.Количество<br />
Массив Элементы[Кво-2] тип Объект<br />
Для Инд=1 По Кво-1<br />
Элементы[Инд-1]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат ВыполнитьДействие(Действие, ИД, Элементы, Окруж)<br />
КонецЕсли<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ВыполнитьДействие(Действие тип Объект, ИД тип Строка, Аргументы тип Объект[], Окруж тип клОкружение) тип Объект<br />
Если Действие ЭтоТип ФункцияСМассивомОперандов Для ФСМО<br />
Возврат ФСМО.Invoke(ИД,Объект(Аргументы))<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСОднимОперандом Для ФСОО<br />
Возврат ФСОО.Invoke(ИД,Аргументы[0])<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСДвумяОперандами Для ФСДО<br />
Возврат ФСДО.Invoke(ИД,Аргументы[0],Аргументы[1])<br />
<br />
ИначеЕсли Действие ЭтоТип клФункцияПользователя Для ФПЛЗ<br />
<br />
ОкружФункции = Новый клОкружение(ФПЛЗ.ИдентификаторыПараметров,Аргументы,ФПЛЗ.Окружение)<br />
Возврат Вычислить(ФПЛЗ.ТелоФункции,ОкружФункции)<br />
<br />
//??????? ИначеЕсли Действие ЭтоТип Тип("System.Delegate") Для ФСД<br />
//ошибка на слове Для<br />
<br />
ИначеЕсли Действие ЭтоТип System.Delegate Для ФСД<br />
Возврат ФСД.DynamicInvoke(Аргументы)<br />
<br />
ИначеЕсли Найти(ИД,".")>0<br />
//вызов метода объекта<br />
<br />
<br />
ИначеЕсли Аргументы.Количество>0<br />
ВызватьИсключение "Значение вызывается как действие."<br />
<br />
Иначе<br />
//просто значение<br />
Возврат Действие<br />
КонецЕсли<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
#Область ВстроенныеФункцииЯзыка<br />
<br />
//---------------------------<br />
Функция ОператорСМассивомОперандов(ИмяФункции тип Строка, Парам Операнды тип Объект[]) тип Объект <br />
Если Операнды Это Неопределено<br />
Возврат 0<br />
КонецЕсли<br />
Если Операнды.Количество=0<br />
ВызватьИсключение "Не достаточно операндов в Функции "+ИмяФункции+"."<br />
КонецЕсли<br />
Перем Рез тип Объект = Операнды[0]<br />
Для Инд=1 По Операнды.Количество-1<br />
Выбор Для НРег(ИмяФункции)<br />
Когда "+" Тогда <br />
Рез += Операнды[Инд]<br />
Когда "-" Тогда <br />
Рез -= Операнды[Инд]<br />
Когда "*" Тогда <br />
Рез *= Операнды[Инд]<br />
Когда "/" Тогда <br />
Рез /= Операнды[Инд]<br />
Когда "^","**" Тогда <br />
Рез ^= Операнды[Инд]<br />
Когда "макс" Тогда <br />
Если Операнды[Инд] > Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Когда "мин" Тогда <br />
Если Операнды[Инд] < Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецЦикла<br />
Возврат Рез<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда "помодулю" Тогда <br />
Возврат Математика.ПоМодулю(Число(Операнд))<br />
Когда "синус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "косинус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "корень" Тогда <br />
Возврат Число(Математика.Корень(ДВещ(Операнд)))<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда ">" Тогда <br />
Возврат Операнд1 > Операнд2<br />
Когда "<" Тогда <br />
Возврат Операнд1 < Операнд2<br />
Когда ">=" Тогда <br />
Возврат Операнд1 >= Операнд2<br />
Когда "<=" Тогда <br />
Возврат Операнд1 <= Операнд2<br />
Когда "=" Тогда <br />
Возврат Операнд1 = Операнд2<br />
Когда "<>", "!=" Тогда <br />
Возврат Операнд1 <> Операнд2<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
//---------------------------<br />
Функция НайтиТипОбъекта(ИД тип Строка) тип Тип <br />
ИмпортИмён System<br />
ИмпортИмён System.Reflection<br />
Перем НашлиТип тип Тип = Неопределено<br />
//ищем в загруженных сборках <br />
Для Ассм тип Assembly Из AppDomain.CurrentDomain.GetAssemblies<br />
Для СИД тип Строка Из {ИД,"Промкод.Перфолента."+ИД}<br />
тп = Ассм.GetType(СИД, Ложь, Истина)<br />
Если тп ЭтоНе Неопределено<br />
Если НашлиТип Это Неопределено<br />
НашлиТип=тп<br />
Прервать<br />
Иначе<br />
ВызватьИсключение "Указанный тип "+ИД+" существует в нескольких загруженных сборках."<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЦикла<br />
Если НашлиТип Это Неопределено<br />
ВызватьИсключение "Указанный тип "+ИД+" НЕ найден в загруженных сборках."<br />
КонецЕсли<br />
Возврат НашлиТип<br />
КонецФункции <br />
<br />
КонецПрограммы <br />
<br />
//==========================================================================================<br />
#Область ВспомогательныеКлассы<br />
<br />
Делегат Функция ФункцияСМассивомОперандов(ИмяФункции тип Строка, Операнды тип Объект[]) тип Объект <br />
Делегат Функция ФункцияСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект<br />
Делегат Функция ФункцияСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект<br />
<br />
//окружение хранит список действий и переменных<br />
//***************************<br />
Класс клОкружение <br />
Поле _Окружение тип Структура = Новый Структура<br />
Поле _ВнешнееОкружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(ВнешнееОкружение тип клОкружение = Неопределено)<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип Строка[], Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип клСписок, Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ДобавитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Добавить(НРег(Идентификатор),Действие)<br />
КонецПроцедуры<br />
//---------------------------<br />
&ВидноВсем <br />
Функция НайтиОкружение(Идентификатор тип Строка) тип клОкружение<br />
Если _Окружение.СодержитКлюч(НРег(Идентификатор)) Тогда<br />
Возврат ЭтотОбъект<br />
ИначеЕсли _ВнешнееОкружение Это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли<br />
Возврат _ВнешнееОкружение.НайтиОкружение(Идентификатор)<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Функция ПолучитьДействие(Идентификатор тип Строка) тип Объект<br />
Возврат _Окружение.Получить(НРег(Идентификатор))<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ВставитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Вставить(НРег(Идентификатор), Действие)<br />
КонецПроцедуры <br />
КонецКласса<br />
<br />
//функция определяемая пользователем<br />
//***************************<br />
Класс клФункцияПользователя<br />
&ВидноВсем <br />
Поле ИдентификаторыПараметров тип клСписок<br />
&ВидноВсем <br />
Поле ТелоФункции тип Объект<br />
&ВидноВсем <br />
Поле Окружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(пИдентификаторыПараметров тип клСписок, пТелоФункции тип Объект, пОкруж тип клОкружение)<br />
Присвоить ИдентификаторыПараметров, ТелоФункции, Окружение = пИдентификаторыПараметров, пТелоФункции, пОкруж<br />
КонецКонструктора<br />
КонецКласса<br />
<br />
//список хранит элементы находящиеся в круглых скобках<br />
//***************************<br />
Класс клСписок <br />
<br />
&ВидноВсем <br />
Поле Данные тип Массив = Новый Массив<br />
<br />
&ВидноВсем <br />
Конструктор() <br />
КонецКонструктора <br />
<br />
&ВидноВсем <br />
Конструктор(МассивСтрок тип Строка[]) <br />
Данные.ДобавитьВсе(МассивСтрок)<br />
КонецКонструктора <br />
<br />
&ВидноВсем<br />
Процедура ВКонец(Значение тип Объект)<br />
Данные.Добавить(Значение) <br />
КонецПроцедуры<br />
<br />
&ВидноВсем<br />
Функция ПоИндексу(Индекс тип Целое) тип Объект <br />
Возврат Данные.Получить(Индекс)<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Извлечь(Индекс тип Целое) тип Объект <br />
Элемент = Данные.Получить(Индекс)<br />
Данные.Удалить(Индекс)<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Количество() тип Целое <br />
Возврат Данные.Количество<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
//идентификатор хранит имя действия <br />
//***************************<br />
Класс клИдентификатор<br />
<br />
Поле _ИД тип Строка <br />
<br />
&ВидноВсем <br />
Конструктор(ИД тип Строка) <br />
_ИД=ИД<br />
КонецКонструктора <br />
<br />
//переопределим функцию преобразования к строке<br />
&ВидноВсем, Переопределение<br />
Функция ToString() тип Строка <br />
Возврат _ИД<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
#КонецОбласти <br />
<br />
== См. также ==<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Скрипты и программы на языке Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%AF%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%9F%D0%B5%D1%80%D1%84%D0%BE_(%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4)&diff=8051Язык программирования Перфо (Исходный код)2020-08-05T18:01:48Z<p>Дизайнер: Новая страница: « // интерпретатор языка программирования Перфо // русскоязычный вариант языка похожего…»</p>
<hr />
<div><br />
// интерпретатор языка программирования Перфо<br />
// русскоязычный вариант языка похожего на Scheme<br />
// однако, унифицированный с языком Перфолента<br />
<br />
/*<br />
Описание языка: <br />
- есть 3 типа сущностей Идентификаторы, Значения и Списки<br />
- значениями могут быть простые типы: строки, символы, числа, даты, булево и неопределено, <br />
а так же созданные во время выполнения объекты и делегаты действий<br />
- синтаксис значений такой же, как в языке Перфолента: <br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
- любой другой набор символов не содержащий пробельных символов является идентификатором: А1, $SYM, !!!Ошибка!!!<br />
- списки состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
- действие это список, первым элементом которого является идентификатор, а остальные элементы являются параметрами действия<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
- идентификатор может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
- параметр действия может быть любой сущностью или последовательностью<br />
- последовательность это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
- оператор это специальная форма действия, в которой смысл и назначение параметров, <br />
а так же их последовательность выполнения определены стандартом языка,<br />
например, (Если (Условие) (СписокДействий1) (СписокДействий2))<br />
или (Перем ИмяПеременной Значение)<br />
Возвращаемые значения:<br />
- значение возвращает само себя<br />
- идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
- действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
- оператор возвращает то, что определено стандартом языка<br />
- последовательность возвращает результат последнего элемента<br />
<br />
*/<br />
<br />
#ТипСборки КонсольноеПриложение<br />
#ИспользоватьСтандартнуюБиблиотеку<br />
<br />
ИмпортИмён Промкод.Перфолента.Консоль<br />
<br />
//***************************<br />
&ВидноВсем<br />
Программа Перфо<br />
<br />
//стандартное окружение хранит значения и действий<br />
//заданные стандартом языка<br />
Поле СтандартноеОкружение тип клОкружение = ЗаполнитьСтандартноеОкружение()<br />
<br />
//глобальное окружение хранит значения переменных и определения действий<br />
//в глобальном контексте выполнения программы<br />
Поле ГлобОкружение тип клОкружение = Новый клОкружение(СтандартноеОкружение)<br />
<br />
//оператор (Отладка Истина) включает вывод сообщений об ошибках в консоль<br />
//при выполнении скрипта запущенного из командной строки<br />
//если отладка выключена, то консоль просто закроется и программа вернет код ошибки окружению ОС<br />
Поле Отладка тип Булево = Ложь <br />
<br />
//используем функцию Старт, а не процедуру, что бы вернуть операционной системе код возврата<br />
//---------------------------<br />
Функция Старт() тип Целое<br />
<br />
Если ЭтаПрограмма.КоличествоАргументовКоманднойСтроки > 0<br />
<br />
// выполняем скрипт из файла<br />
<br />
Файл = СокрЛП(ЭтаПрограмма.ПолучитьАргументКоманднойСтроки(0))<br />
Если ФС.ФайлСуществует(Файл) <br />
Попытка<br />
ТекстПрограммы = ФС.ПрочитатьТекст(Файл) <br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Исключение Ош<br />
Если Отладка<br />
ВыводСтроки "Ошибка выполнения программы (код 1): "+Ош.ОписаниеОшибки <br />
Пауза<br />
КонецЕсли <br />
Возврат 1 //ошибка при выполнении программы<br />
КонецПопытки<br />
Иначе<br />
Если Отладка<br />
ВыводСтроки "Ошибка (код 2): Не найден файл программы "+Файл <br />
Пауза<br />
КонецЕсли <br />
Возврат 2 //ошибка: файл программы не найден<br />
КонецЕсли<br />
Если Отладка<br />
ПереносСтроки<br />
Пауза<br />
КонецЕсли <br />
Возврат 0 //ошибок нет<br />
<br />
Иначе<br />
<br />
// интерактивная работа<br />
<br />
ВыводПС("Перфо - простой интерпретатор русского языка похожего на Scheme")<br />
Цикл<br />
ПереносСтроки<br />
Вывод("Перфо> ")<br />
ТекстПрограммы = ПрочитатьСтроку()<br />
Попытка<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Если Результат ЭтоНе Неопределено<br />
Вывод(РезультатВСтроку(Результат))<br />
КонецЕсли<br />
Исключение Ош<br />
ВыводПС("Ошибка: "+Ош.ОписаниеОшибки)<br />
КонецПопытки<br />
КонецЦикла<br />
<br />
КонецЕсли<br />
<br />
КонецФункции<br />
<br />
//запускает на выполнение текст программы с установкой переменной ЭтотОбъект<br />
//используется для запуска скрипта из других программ<br />
//---------------------------<br />
&ВидноВсем<br />
Функция ВыполнитьПрограмму(ТекстПрограммы тип Строка, ЗначениеПеременнойЭтотОбъект тип Объект = Неопределено) тип Строка <br />
Попытка<br />
ГлобОкружение.ДобавитьДействие("этотобъект", ЗначениеПеременнойЭтотОбъект)<br />
Результат = Выполнить(Компилировать(ТекстПрограммы))<br />
Возврат РезультатВСтроку(Результат)<br />
Исключение Ош<br />
Если Отладка<br />
Возврат "Ошибка: "+Ош.ОписаниеОшибки <br />
КонецЕсли <br />
Возврат Неопределено<br />
КонецПопытки<br />
КонецФункции <br />
<br />
#Область ФункцииКомпилятора<br />
<br />
//запускает на выполнение откомпилированную программу<br />
//---------------------------<br />
Функция Выполнить(СписокВыражений тип клСписок) тип Объект<br />
Результат = Неопределено<br />
Для Инд=0 По СписокВыражений.Количество-1<br />
Результат = Вычислить(СписокВыражений.ПоИндексу(Инд),ГлобОкружение) <br />
КонецЦикла<br />
Возврат Результат<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Компилировать(ТекстПрограммы тип Строка) тип Объект<br />
ПредставлениеПрограммы = Новый клСписок<br />
Спис = РазобратьНаТокены(ТекстПрограммы)<br />
Пока Спис.Количество > 0<br />
ПредставлениеПрограммы.ВКонец(ОбработатьТокены(Спис))<br />
КонецЦикла<br />
Возврат ПредставлениеПрограммы<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РазобратьНаТокены(ТекстПрограммы тип Строка) тип клСписок<br />
<br />
Пт = Новый ПостроительТекста<br />
<br />
//выделим строки, символы и даты перед тем, как разделять по пробелам<br />
//т.к. в них бывают пробелы, табуляции и т.д...<br />
ДлинаТекста=СтрДлина(ТекстПрограммы)<br />
Если ДлинаТекста<2<br />
Пт{ТекстПрограммы}<br />
Иначе<br />
масСтроки=Новый Массив<br />
Символ14=""+Символ(14)<br />
МаксЦелое=2147483647<br />
Поз1=1<br />
Цикл<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1)<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1)<br />
Если Поз2=0 и Поз3=0<br />
Пт{Сред(ТекстПрограммы,Поз1)}<br />
Прервать<br />
КонецЕсли<br />
Поз2=?(Поз2=0,МаксЦелое,Поз2)<br />
Поз3=?(Поз3=0,МаксЦелое,Поз3)<br />
Если Поз2 < Поз3 <br />
//нашли "<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз2-Поз1)}<br />
Поз1=Поз2<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз1+1)<br />
~ПроверкаВторойКавычки:<br />
Если Поз2=0<br />
ВызватьИсключение "Строка не закрыта двойной кавычкой."<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если НРег(Симв)="с" или НРег(Симв)="c" //рус и англ<br />
//берем знак символа<br />
Поз2++<br />
ИначеЕсли Симв=""""<br />
//берем продолжение строки<br />
Поз2=СтрНайти(ТекстПрограммы,"""",,Поз2+2)<br />
Перейти ~ПроверкаВторойКавычки:<br />
ИначеЕсли Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после строки."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз2-Поз1+1))<br />
Поз1=Поз2+1<br />
КонецЕсли<br />
Иначе<br />
//нашли '<br />
Пт{Сред(ТекстПрограммы,Поз1,Поз3-Поз1)}<br />
Поз1=Поз3<br />
Поз3=СтрНайти(ТекстПрограммы,"'",,Поз1+1)<br />
Если Поз3=0<br />
ВызватьИсключение "Дата не закрыта одинарной кавычкой"<br />
Иначе<br />
Если ДлинаТекста > Поз2<br />
Симв=Сред(ТекстПрограммы,Поз2+1,1)<br />
Если Симв=")"<br />
//ничего делать не надо<br />
ИначеЕсли Символы.ЭтоПробельный(Симв)<br />
//ничего делать не надо<br />
Иначе<br />
ВызватьИсключение "Не известный символ после даты."<br />
КонецЕсли<br />
КонецЕсли<br />
Пт{Символ14+СокрЛП(масСтроки.Количество)}<br />
масСтроки.Добавить(Сред(ТекстПрограммы,Поз1,Поз3-Поз1+1))<br />
Поз1=Поз3+1<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЕсли<br />
ТекстПрограммы=Пт.ВСтроку<br />
<br />
//уберем комментарии и директивы препрцессора<br />
Пт = Новый ПостроительТекста<br />
Токены=ТекстПрограммы.Разделить({Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Поз=Найти(Токены[Инд],"#") <br />
Если Поз<>1<br />
Поз=Найти(Токены[Инд],"//") <br />
Если Поз>0<br />
Пт{Лев(Токены[Инд],Поз-1)}<br />
Иначе<br />
Пт{Токены[Инд]}<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
<br />
//разделим на токены<br />
Токены=Пт.ВСтроку.Заменить("("," ( ").Заменить(")"," ) ").Разделить({" ",Символы.НПП,Символы.Таб,Символы.ВК,Символы.ПС},Ложь)<br />
Для Инд=0 По Токены.Количество-1<br />
Если Лев(Токены[Инд],1)=Символ14<br />
Токены[Инд]=масСтроки[Целое(Сред(Токены[Инд],2))]<br />
КонецЕсли<br />
КонецЦикла<br />
Возврат Новый клСписок(Токены) <br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОбработатьТокены(Токены тип клСписок) тип Объект<br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Неожиданный конец программы."<br />
КонецЕсли<br />
Токен = Токены.Извлечь(0)<br />
Если "(" = Токен<br />
Спис = Новый клСписок<br />
Цикл <br />
Если Токены.Количество=0 <br />
ВызватьИсключение "Ожидается символ )."<br />
КонецЕсли<br />
Прервать Если Токены.ПоИндексу(0) = ")"<br />
Спис.ВКонец(ОбработатьТокены(Токены))<br />
КонецЦикла<br />
Токены.Извлечь(0) //убираем )<br />
Возврат Спис<br />
ИначеЕсли ")" = Токен<br />
ВызватьИсключение "Неожиданный символ )."<br />
Иначе<br />
Возврат Атом(Токен)<br />
КонецЕсли<br />
КонецФункции <br />
<br />
//---------------------------<br />
// Распознаёт неопределено, числа, строки, символы, булево, даты и идентификаторы<br />
Функция Атом(Токен тип Строка) тип Объект <br />
Если НРег(Токен)="неопределено"<br />
//это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("""") и Токен.ЗаканчиваетсяНа("""")<br />
//это строка<br />
Возврат Токен.Сред(2,СтрДлина(Токен)-2)<br />
КонецЕсли <br />
Если СтрДлина(Токен)=4 и Токен.НачинаетсяС("""") и (Токен.ЗаканчиваетсяНа("""с") или Токен.ЗаканчиваетсяНа("""c")) //рус и англ<br />
//это символ<br />
Возврат Символ(Токен.Сред(2,1))<br />
КонецЕсли <br />
Если Токен.НачинаетсяС("'") и Токен.ЗаканчиваетсяНа("'")<br />
Попытка<br />
//это дата<br />
Возврат Дата(Токен.Сред(2,СтрДлина(Токен)-2))<br />
КонецПопытки<br />
КонецЕсли <br />
Бул=Ложь<br />
Чис=0ч<br />
//числа записываются через точку, но и через запятую сработает<br />
Если РаспознатьЧисло(СтрЗаменить(Токен,".",Сред(Строка(1.1),2,1)),Чис)<br />
//это число<br />
Возврат Чис<br />
ИначеЕсли РаспознатьБулево(Токен,Бул)<br />
//это булево<br />
Возврат Бул<br />
КонецЕсли<br />
//это какой-то идентификатор<br />
Возврат Новый клИдентификатор(Токен)<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция РезультатВСтроку(Результат тип Объект) тип Строка <br />
Если Результат Это Неопределено<br />
Возврат ""<br />
ИначеЕсли Результат ЭтоТип клСписок Для Спис<br />
Стр = "("<br />
Для Об Из Спис.Данные<br />
Стр &= ?(Стр = "(",""," ")+РезультатВСтроку(Об)<br />
КонецЦикла<br />
Возврат Стр+")"<br />
Иначе<br />
Возврат Строка(Результат)<br />
КонецЕсли <br />
КонецФункции <br />
<br />
//тут можно определить стандартные функции и значения языка<br />
//все эти значения переопределяемые во время выполнения<br />
//---------------------------<br />
Функция ЗаполнитьСтандартноеОкружение() тип клОкружение <br />
Окруж = Новый клОкружение()<br />
Окруж.ДобавитьДействие{<br />
{"вкпс", Символы.ВКПС}, <br />
{"вк", Символы.ВК}, <br />
{"пс", Символы.ПС}, <br />
{"таб", Символы.Таб}, <br />
{"нпп", Символы.НПП}, <br />
{"упс", Символы.УПС}, <br />
<br />
{"+", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"-", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"*", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"/", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"^", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")}, <br />
{"**", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"макс", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
{"мин", ПолучитьДелегат(,ОператорСМассивомОперандов,"ФункцияСМассивомОперандов")},<br />
<br />
{">", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{">=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")}, <br />
{"<>", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
{"!=", ПолучитьДелегат(,ОператорСДвумяОперандами,"ФункцияСДвумяОперандами")},<br />
<br />
{"помодулю", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"корень", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"синус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")},<br />
{"косинус", ПолучитьДелегат(,ОператорСОднимОперандом,"ФункцияСОднимОперандом")}<br />
<br />
//{"append", op.add}, <br />
//{"apply", apply},<br />
//{"begin", lambda *x: x[-1]},<br />
//{"car", lambda x: x[0]},<br />
//{"cdr", lambda x: x[1:]}, <br />
//{"cons", lambda x,y: [x] + y},<br />
//{"eq?", op.is_}, <br />
//{"equal?", op.eq}, <br />
//{"length", len}, <br />
//{"list", lambda *x: list(x)}, <br />
//{"list?", lambda x: isinstance(x,list)}, <br />
//{"map", map},<br />
//{"not", op.not_},<br />
//{"null?", lambda x: x == []}, <br />
//{"number?", lambda x: isinstance(x, Number)}, <br />
//{"procedure?", callable},<br />
//{"round", round,<br />
//{"symbol?", lambda x: isinstance(x, Symbol)}<br />
}<br />
Возврат Окруж<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция Вычислить(Элемент тип Объект, Окруж тип клОкружение) тип Объект<br />
<br />
Если Элемент ЭтоТип клИдентификатор Для ТекИдентификатор <br />
//получим значение переменной<br />
ТекОкруж = Окруж.НайтиОкружение(ТекИдентификатор)<br />
Если ТекОкруж Это Неопределено<br />
ВызватьИсключение "Не найден идентификатор "+ТекИдентификатор <br />
Иначе<br />
Возврат ТекОкруж.ПолучитьДействие(ТекИдентификатор)<br />
КонецЕсли<br />
КонецЕсли<br />
Если Элемент ЭтоНеТип клСписок <br />
//возвращаем атом<br />
Возврат Элемент <br />
КонецЕсли<br />
<br />
//это точно список<br />
<br />
//?????? РУГАЕТСЯ<br />
//Спис = Элемент КАК клСписок<br />
<br />
Спис = ТипКТипу(Элемент,"клСписок")<br />
Если Спис.Количество=0<br />
Возврат Неопределено <br />
КонецЕсли<br />
Перем ИД тип Строка = ""<br />
Если Спис.ПоИндексу(0) ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
Рез = Вычислить(Спис.ПоИндексу(0), Окруж)<br />
Если Рез ЭтоТип клИдентификатор Для ТекИдентификатор<br />
//все-таки первый элемент это идентификатор<br />
ИД=НРег(ТекИдентификатор.ВСтроку)<br />
<br />
Иначе<br />
//обходим последовательность<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Рез=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат Рез<br />
КонецЕсли<br />
КонецЕсли<br />
<br />
Если ИД = "пауза"<br />
//выводим в консоль сообщение и ждем нажатия любой клавиши<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Пауза не имеет операндов." <br />
КонецЕсли<br />
Пауза<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "очистить"<br />
//очищаем экран консоли<br />
Если Спис.Количество<>1<br />
ВызватьИсключение "Оператор Очистить не имеет операндов." <br />
КонецЕсли<br />
Очистить<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "отладка"<br />
//включаем/выключаем режим отладки скрипта<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Отладка." <br />
КонецЕсли<br />
Отладка=Булево(Вычислить(Спис.ПоИндексу(1), Окруж))<br />
Возврат Отладка<br />
<br />
ИначеЕсли ИД = "ввод" <br />
//вычисляем и выводим в консоль все приглашения<br />
//и ждем ввода строки в консоль и нажатия клавиши Ввод (Enter)<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат ПрочитатьСтроку()<br />
<br />
ИначеЕсли ИД = "вывод" <br />
//вычисляем и выводим в консоль все элементы списка<br />
Кво=Спис.Количество<br />
Для Инд=1 По Кво-1<br />
Вывод(РезультатВСтроку(Вычислить(Спис.ПоИндексу(Инд), Окруж)))<br />
КонецЦикла<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "идент"<br />
//вычисляем операнд и превращаем результат в идентификатор<br />
Если Спис.Количество<>2<br />
ВызватьИсключение "Не верное число операндов в операторе Идент." <br />
КонецЕсли<br />
Возврат Новый клИдентификатор(РезультатВСтроку(Вычислить(Спис.ПоИндексу(1), Окруж)))<br />
<br />
ИначеЕсли ИД = "если" <br />
//вычисляем условие<br />
//если условие выполнилось, то вычисляем Список1<br />
//иначе, вычисляем Список2<br />
//возвращаем результат того списка, который вычислялся<br />
//(Если (Условие) Список1 Список2)<br />
Если Спис.Количество<>4<br />
ВызватьИсключение "Не верное число операндов в операторе ?." <br />
КонецЕсли<br />
Возврат Вычислить(?(Булево(Вычислить(Спис.ПоИндексу(1), Окруж)),Спис.ПоИндексу(2),Спис.ПоИндексу(3)), Окруж)<br />
<br />
ИначеЕсли ИД = "новый" <br />
//создать новый объект .Net из загруженных сборок <br />
//пространство имён Промкод.Перфолента импортировано по умолчанию<br />
//например, (Новый Массив) или (Новый Структура "Вид,Количество", "Простой", 5)<br />
Если Спис.Количество<2<br />
ВызватьИсключение "Не верное число операндов в операторе Новый." <br />
КонецЕсли<br />
//идентификатор типа объекта может вычисляться налету <br />
//например, (Новый (Идент (+ "Мас" "сив")))<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Новый не является идентификатором." <br />
КонецЕсли<br />
ТипОбъекта = НайтиТипОбъекта(Рез)<br />
Кво=Спис.Количество<br />
Массив Парамс[Кво-3] тип Объект<br />
Для Инд=2 По Кво-1<br />
Парамс[Инд-2]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат System.Activator.CreateInstance(ТипОбъекта,Парамс)<br />
<br />
ИначеЕсли ИД = "перем" <br />
//определяем переменную<br />
//например, присвоим переменной А1 значение 100: (Перем А1 100)<br />
//переменная сохраняется в текущее окружение<br />
Если Спис.Количество<>3<br />
ВызватьИсключение "Не верное число операндов в операторе Перем." <br />
КонецЕсли<br />
//идентификатор переменной может вычисляться налету <br />
//например, (Перем (Идент (+ "А" "1")) 100)<br />
Рез = Спис.ПоИндексу(1)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Второй параметр в операторе Перем не является идентификатором." <br />
КонецЕсли<br />
Зн = Вычислить(Спис.ПоИндексу(2), Окруж)<br />
Окруж.ВставитьДействие(Рез, Зн)<br />
Возврат Неопределено<br />
<br />
ИначеЕсли ИД = "функ" <br />
//определение анонимной функции (Функ (ИдентификаторыПараметров...) ТелоФункции)<br />
//анонимная функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
ВызватьИсключение "Имя параметра № "+(Инд+1)+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЦикла<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
Возврат Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
ИначеЕсли ИД = "функция" <br />
//определение функции (Функция (ИмяФункции ИдентификаторыПараметров...) ТелоФункции)<br />
//функция получает текущее окружение<br />
Если Спис.Количество<3<br />
ВызватьИсключение "Не верное число операндов в операторе Функция." <br />
КонецЕсли<br />
Если Спис.ПоИндексу(1) ЭтоТип клСписок Для СписП<br />
Перем ИмяФункции тип Строка = Неопределено<br />
СписокИдентификаторовПараметров = Новый клСписок<br />
Для Инд=0 По СписП.Количество-1<br />
Рез = СписП.ПоИндексу(Инд)<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Рез = Вычислить(Рез, Окруж)<br />
КонецЕсли<br />
Если Рез ЭтоНеТип клИдентификатор<br />
Если Инд=0<br />
ВызватьИсключение "Имя Функции не является идентификатором." <br />
Иначе<br />
ВызватьИсключение "Имя параметра № "+Инд+" в операторе Функция не является идентификатором." <br />
КонецЕсли<br />
КонецЕсли<br />
Если Инд=0<br />
ИмяФункции = Рез<br />
Иначе<br />
СписокИдентификаторовПараметров.ВКонец(Рез)<br />
КонецЕсли<br />
КонецЦикла<br />
Если ИмяФункции = Неопределено<br />
ВызватьИсключение "Имя функции неопределено." <br />
КонецЕсли<br />
ТелоФункции = Новый клСписок<br />
Для Инд=2 По Спис.Количество-1<br />
ТелоФункции.ВКонец(Спис.ПоИндексу(Инд))<br />
КонецЦикла<br />
ФункП = Новый клФункцияПользователя(СписокИдентификаторовПараметров,ТелоФункции,Окруж)<br />
Окруж.ВставитьДействие(ИмяФункции, ФункП)<br />
Возврат Неопределено<br />
Иначе<br />
ВызватьИсключение "Второй операнд в операторе Функция не является списком параметров." <br />
КонецЕсли<br />
<br />
Иначе <br />
//(Действие Параметры...)<br />
//остался только один вариант<br />
//надо выполнить действие из окружения<br />
Действие = Вычислить(ТекИдентификатор, Окруж)<br />
Кво=Спис.Количество<br />
Массив Элементы[Кво-2] тип Объект<br />
Для Инд=1 По Кво-1<br />
Элементы[Инд-1]=Вычислить(Спис.ПоИндексу(Инд), Окруж)<br />
КонецЦикла<br />
Возврат ВыполнитьДействие(Действие, ИД, Элементы, Окруж)<br />
КонецЕсли<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ВыполнитьДействие(Действие тип Объект, ИД тип Строка, Аргументы тип Объект[], Окруж тип клОкружение) тип Объект<br />
Если Действие ЭтоТип ФункцияСМассивомОперандов Для ФСМО<br />
Возврат ФСМО.Invoke(ИД,Объект(Аргументы))<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСОднимОперандом Для ФСОО<br />
Возврат ФСОО.Invoke(ИД,Аргументы[0])<br />
<br />
ИначеЕсли Действие ЭтоТип ФункцияСДвумяОперандами Для ФСДО<br />
Возврат ФСДО.Invoke(ИД,Аргументы[0],Аргументы[1])<br />
<br />
ИначеЕсли Действие ЭтоТип клФункцияПользователя Для ФПЛЗ<br />
<br />
ОкружФункции = Новый клОкружение(ФПЛЗ.ИдентификаторыПараметров,Аргументы,ФПЛЗ.Окружение)<br />
Возврат Вычислить(ФПЛЗ.ТелоФункции,ОкружФункции)<br />
<br />
//??????? ИначеЕсли Действие ЭтоТип Тип("System.Delegate") Для ФСД<br />
//ошибка на слове Для<br />
<br />
ИначеЕсли Действие ЭтоТип System.Delegate Для ФСД<br />
Возврат ФСД.DynamicInvoke(Аргументы)<br />
<br />
ИначеЕсли Найти(ИД,".")>0<br />
//вызов метода объекта<br />
<br />
<br />
ИначеЕсли Аргументы.Количество>0<br />
ВызватьИсключение "Значение вызывается как действие."<br />
<br />
Иначе<br />
//просто значение<br />
Возврат Действие<br />
КонецЕсли<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
#Область ВстроенныеФункцииЯзыка<br />
<br />
//---------------------------<br />
Функция ОператорСМассивомОперандов(ИмяФункции тип Строка, Парам Операнды тип Объект[]) тип Объект <br />
Если Операнды Это Неопределено<br />
Возврат 0<br />
КонецЕсли<br />
Если Операнды.Количество=0<br />
ВызватьИсключение "Не достаточно операндов в Функции "+ИмяФункции+"."<br />
КонецЕсли<br />
Перем Рез тип Объект = Операнды[0]<br />
Для Инд=1 По Операнды.Количество-1<br />
Выбор Для НРег(ИмяФункции)<br />
Когда "+" Тогда <br />
Рез += Операнды[Инд]<br />
Когда "-" Тогда <br />
Рез -= Операнды[Инд]<br />
Когда "*" Тогда <br />
Рез *= Операнды[Инд]<br />
Когда "/" Тогда <br />
Рез /= Операнды[Инд]<br />
Когда "^","**" Тогда <br />
Рез ^= Операнды[Инд]<br />
Когда "макс" Тогда <br />
Если Операнды[Инд] > Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Когда "мин" Тогда <br />
Если Операнды[Инд] < Рез <br />
Рез = Операнды[Инд]<br />
КонецЕсли<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецЦикла<br />
Возврат Рез<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда "помодулю" Тогда <br />
Возврат Математика.ПоМодулю(Число(Операнд))<br />
Когда "синус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "косинус" Тогда <br />
Возврат Число(Математика.Синус(ДВещ(Операнд)))<br />
Когда "корень" Тогда <br />
Возврат Число(Математика.Корень(ДВещ(Операнд)))<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
//---------------------------<br />
Функция ОператорСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект <br />
Выбор Для НРег(ИмяФункции)<br />
Когда ">" Тогда <br />
Возврат Операнд1 > Операнд2<br />
Когда "<" Тогда <br />
Возврат Операнд1 < Операнд2<br />
Когда ">=" Тогда <br />
Возврат Операнд1 >= Операнд2<br />
Когда "<=" Тогда <br />
Возврат Операнд1 <= Операнд2<br />
Когда "=" Тогда <br />
Возврат Операнд1 = Операнд2<br />
Когда "<>", "!=" Тогда <br />
Возврат Операнд1 <> Операнд2<br />
Иначе<br />
ВызватьИсключение "Функция "+ИмяФункции+" не определена."<br />
КонецВыбора<br />
КонецФункции <br />
<br />
#КонецОбласти <br />
<br />
//---------------------------<br />
Функция НайтиТипОбъекта(ИД тип Строка) тип Тип <br />
ИмпортИмён System<br />
ИмпортИмён System.Reflection<br />
Перем НашлиТип тип Тип = Неопределено<br />
//ищем в загруженных сборках <br />
Для Ассм тип Assembly Из AppDomain.CurrentDomain.GetAssemblies<br />
Для СИД тип Строка Из {ИД,"Промкод.Перфолента."+ИД}<br />
тп = Ассм.GetType(СИД, Ложь, Истина)<br />
Если тп ЭтоНе Неопределено<br />
Если НашлиТип Это Неопределено<br />
НашлиТип=тп<br />
Прервать<br />
Иначе<br />
ВызватьИсключение "Указанный тип "+ИД+" существует в нескольких загруженных сборках."<br />
КонецЕсли<br />
КонецЕсли<br />
КонецЦикла<br />
КонецЦикла<br />
Если НашлиТип Это Неопределено<br />
ВызватьИсключение "Указанный тип "+ИД+" НЕ найден в загруженных сборках."<br />
КонецЕсли<br />
Возврат НашлиТип<br />
КонецФункции <br />
<br />
КонецПрограммы <br />
<br />
//==========================================================================================<br />
#Область ВспомогательныеКлассы<br />
<br />
Делегат Функция ФункцияСМассивомОперандов(ИмяФункции тип Строка, Операнды тип Объект[]) тип Объект <br />
Делегат Функция ФункцияСОднимОперандом(ИмяФункции тип Строка, Операнд тип Объект) тип Объект<br />
Делегат Функция ФункцияСДвумяОперандами(ИмяФункции тип Строка, Операнд1 тип Объект, Операнд2 тип Объект) тип Объект<br />
<br />
//окружение хранит список действий и переменных<br />
//***************************<br />
Класс клОкружение <br />
Поле _Окружение тип Структура = Новый Структура<br />
Поле _ВнешнееОкружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(ВнешнееОкружение тип клОкружение = Неопределено)<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип Строка[], Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы[Инд]),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(Идентификаторы тип клСписок, Действия тип Объект[], ВнешнееОкружение тип клОкружение = Неопределено)<br />
Кво = Мин(Идентификаторы.Количество,Действия.Количество)<br />
Для Инд=0 По Кво-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Действия[Инд])<br />
КонецЦикла<br />
Если Идентификаторы.Количество > Действия.Количество<br />
//поддержим возможность передавать в функцию меньше параметров, чем задано в её определении <br />
Для Инд=Кво По Идентификаторы.Количество-1<br />
_Окружение.Добавить(НРег(Идентификаторы.ПоИндексу(Инд)),Неопределено)<br />
КонецЦикла<br />
ИначеЕсли Идентификаторы.Количество < Действия.Количество<br />
//а вот лишние параметры это ошибка<br />
ВызватьИсключение "Число реальных параметров функции больше, чем формальных."<br />
КонецЕсли<br />
_ВнешнееОкружение = ВнешнееОкружение<br />
КонецКонструктора<br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ДобавитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Добавить(НРег(Идентификатор),Действие)<br />
КонецПроцедуры<br />
//---------------------------<br />
&ВидноВсем <br />
Функция НайтиОкружение(Идентификатор тип Строка) тип клОкружение<br />
Если _Окружение.СодержитКлюч(НРег(Идентификатор)) Тогда<br />
Возврат ЭтотОбъект<br />
ИначеЕсли _ВнешнееОкружение Это Неопределено<br />
Возврат Неопределено<br />
КонецЕсли<br />
Возврат _ВнешнееОкружение.НайтиОкружение(Идентификатор)<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Функция ПолучитьДействие(Идентификатор тип Строка) тип Объект<br />
Возврат _Окружение.Получить(НРег(Идентификатор))<br />
КонецФункции <br />
//---------------------------<br />
&ВидноВсем <br />
Процедура ВставитьДействие(Идентификатор тип Строка, Действие тип Объект)<br />
_Окружение.Вставить(НРег(Идентификатор), Действие)<br />
КонецПроцедуры <br />
КонецКласса<br />
<br />
//функция определяемая пользователем<br />
//***************************<br />
Класс клФункцияПользователя<br />
&ВидноВсем <br />
Поле ИдентификаторыПараметров тип клСписок<br />
&ВидноВсем <br />
Поле ТелоФункции тип Объект<br />
&ВидноВсем <br />
Поле Окружение тип клОкружение<br />
//---------------------------<br />
&ВидноВсем <br />
Конструктор(пИдентификаторыПараметров тип клСписок, пТелоФункции тип Объект, пОкруж тип клОкружение)<br />
Присвоить ИдентификаторыПараметров, ТелоФункции, Окружение = пИдентификаторыПараметров, пТелоФункции, пОкруж<br />
КонецКонструктора<br />
КонецКласса<br />
<br />
//список хранит элементы находящиеся в круглых скобках<br />
//***************************<br />
Класс клСписок <br />
<br />
&ВидноВсем <br />
Поле Данные тип Массив = Новый Массив<br />
<br />
&ВидноВсем <br />
Конструктор() <br />
КонецКонструктора <br />
<br />
&ВидноВсем <br />
Конструктор(МассивСтрок тип Строка[]) <br />
Данные.ДобавитьВсе(МассивСтрок)<br />
КонецКонструктора <br />
<br />
&ВидноВсем<br />
Процедура ВКонец(Значение тип Объект)<br />
Данные.Добавить(Значение) <br />
КонецПроцедуры<br />
<br />
&ВидноВсем<br />
Функция ПоИндексу(Индекс тип Целое) тип Объект <br />
Возврат Данные.Получить(Индекс)<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Извлечь(Индекс тип Целое) тип Объект <br />
Элемент = Данные.Получить(Индекс)<br />
Данные.Удалить(Индекс)<br />
Возврат Элемент<br />
КонецФункции <br />
<br />
&ВидноВсем<br />
Функция Количество() тип Целое <br />
Возврат Данные.Количество<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
//идентификатор хранит имя действия <br />
//***************************<br />
Класс клИдентификатор<br />
<br />
Поле _ИД тип Строка <br />
<br />
&ВидноВсем <br />
Конструктор(ИД тип Строка) <br />
_ИД=ИД<br />
КонецКонструктора <br />
<br />
//переопределим функцию преобразования к строке<br />
&ВидноВсем, Переопределение<br />
Функция ToString() тип Строка <br />
Возврат _ИД<br />
КонецФункции <br />
<br />
КонецКласса<br />
<br />
#КонецОбласти <br />
<br />
== См. также ==<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Скрипты и программы на языке Перфолента.NET]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE.NET&diff=8050Перфо.NET2020-08-05T17:58:18Z<p>Дизайнер: /* См. также */</p>
<hr />
<div>Перфо - интерпретатор языка программирования Перфо - русскоязычный вариант языка похожего на [[Scheme]], унифицированный с языком [[Перфолента]] / 1С /[[OneScript]]<br />
<br />
== Описание языка: ==<br />
* есть 3 типа сущностей: Идентификаторы, Значения и Списки<br />
* '''значениями''' могут быть простые типы: строки, символы, числа, даты, булево и неопределено или созданные во время выполнения объекты и [[делегаты действий]]<br />
** синтаксис значений такой же, как в языке Перфолента: <br />
<br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
<br />
* '''идентификатор''' - любой другой набор символов не содержащий пробельных символов: А1, $SYM, !!!Ошибка!!!<br />
* '''списки''' состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
** '''действие''' это список, первым элементом которого является '''идентификатор''', а остальные элементы являются '''параметрами действия'''<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
** '''идентификатор''' может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
** '''параметр действия''' может быть любой сущностью или '''последовательностью'''<br />
** '''последовательность''' это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор:<br />
<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
<br />
* '''оператор''' это специальная форма '''действия''', в которой смысл и назначение параметров, а так же их последовательность выполнения определены стандартом языка, например:<br />
<br />
(Если (Условие) (СписокДействий1) (СписокДействий2)) или (Перем ИмяПеременной Значение)<br />
<br />
Возвращаемые значения:<br />
* значение возвращает само себя<br />
* идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
* действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
* оператор возвращает то, что определено стандартом языка<br />
* последовательность возвращает результат последнего элемента<br />
<br />
== См. также ==<br />
* [[Перфолента.NET]]<br />
* [[Перфо (Исходный код)]] языка программирования Перфо на Перфолента.NET<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Перфо]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE.NET&diff=8049Перфо.NET2020-08-05T17:52:19Z<p>Дизайнер: /* Описание языка: */</p>
<hr />
<div>Перфо - интерпретатор языка программирования Перфо - русскоязычный вариант языка похожего на [[Scheme]], унифицированный с языком [[Перфолента]] / 1С /[[OneScript]]<br />
<br />
== Описание языка: ==<br />
* есть 3 типа сущностей: Идентификаторы, Значения и Списки<br />
* '''значениями''' могут быть простые типы: строки, символы, числа, даты, булево и неопределено или созданные во время выполнения объекты и [[делегаты действий]]<br />
** синтаксис значений такой же, как в языке Перфолента: <br />
<br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
<br />
* '''идентификатор''' - любой другой набор символов не содержащий пробельных символов: А1, $SYM, !!!Ошибка!!!<br />
* '''списки''' состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
** '''действие''' это список, первым элементом которого является '''идентификатор''', а остальные элементы являются '''параметрами действия'''<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
** '''идентификатор''' может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
** '''параметр действия''' может быть любой сущностью или '''последовательностью'''<br />
** '''последовательность''' это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор:<br />
<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
<br />
* '''оператор''' это специальная форма '''действия''', в которой смысл и назначение параметров, а так же их последовательность выполнения определены стандартом языка, например:<br />
<br />
(Если (Условие) (СписокДействий1) (СписокДействий2)) или (Перем ИмяПеременной Значение)<br />
<br />
Возвращаемые значения:<br />
* значение возвращает само себя<br />
* идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
* действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
* оператор возвращает то, что определено стандартом языка<br />
* последовательность возвращает результат последнего элемента<br />
<br />
== См. также ==<br />
* [[Перфолента.NET]]<br />
<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Перфо]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE.NET&diff=8048Перфо.NET2020-08-05T17:50:42Z<p>Дизайнер: Новая страница: «Перфо - интерпретатор языка программирования Перфо - русскоязычный вариант языка похоже…»</p>
<hr />
<div>Перфо - интерпретатор языка программирования Перфо - русскоязычный вариант языка похожего на [[Scheme]], унифицированный с языком [[Перфолента]] / 1С /[[OneScript]]<br />
<br />
== Описание языка: ==<br />
* есть 3 типа сущностей: Идентификаторы, Значения и Списки<br />
* '''значениями''' могут быть простые типы: строки, символы, числа, даты, булево и неопределено или созданные во время выполнения объекты и [[делегаты действий]]<br />
** синтаксис значений такой же, как в языке Перфолента: <br />
<br />
"строка" - строка, "С"с - символ, 4.537 - число, '23.07.2020' - дата, Истина - булево, Неопределено <br />
<br />
* '''идентификатор''' - любой другой набор символов не содержащий пробельных символов: А1, $SYM, !!!Ошибка!!!<br />
* '''списки''' состоят из любых сущностей разделенных пробелами и заключенных в круглые скобки: (+ 3 4 5)<br />
** '''действие''' это список, первым элементом которого является идентификатор, а остальные элементы являются параметрами действия<br />
(ИдентификаторДействия Параметр1 Параметр2 ... ПараметрН), например, (мин 34 9 100)<br />
*** '''идентификатор''' может быть вычисляемым ((Идент "ИдентификаторДействия") Параметр1 Параметр2 ... ПараметрН)<br />
*** '''параметр действия''' может быть любой сущностью или последовательностью<br />
**** '''последовательность''' это список состоящий из любых сущностей, у которого первый элемент НЕ идентификатор:<br />
<br />
(Значение1 Значение2 Значение3) или ((Действие1) (Действие2) (Действие3)) или ((Действие1) (Действие2) Значение1)<br />
<br />
* '''оператор''' это специальная форма действия, в которой смысл и назначение параметров, а так же их последовательность выполнения определены стандартом языка, например:<br />
<br />
(Если (Условие) (СписокДействий1) (СписокДействий2)) или (Перем ИмяПеременной Значение)<br />
<br />
Возвращаемые значения:<br />
* значение возвращает само себя<br />
* идентификатор возвращает сопоставленное ему значение, в том числе, делегат действия, идентификатор или неопределено<br />
* действие может вернуть значение, делегат действия, идентификатор или неопределено<br />
* оператор возвращает то, что определено стандартом языка<br />
* последовательность возвращает результат последнего элемента<br />
== См. также ==<br />
* [[Перфолента.NET]]<br />
<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Перфо]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8047Перфолента.NET2020-08-05T17:39:56Z<p>Дизайнер: /* Версии */</p>
<hr />
<div>'''Перфолента.Net''' - объектно ориентированный язык программирования с русскоязычным синтаксисом 1С. Работает под Windows 7/10 на платформе .NET. Имеет строгую и динамическую типизацию. Текущая версия 0.45<br />
<br />
[[Файл:Перфолента.NET.jpg|мини|слева|Логотип Перфолента.NET]]<br />
<br />
Пытаться создать статью о Перфолента.NET в википедии не имеет смысла - удаляется в течении 1 часа без обсуждения.<br />
<br />
== Версии ==<br />
* Текущая версия 0.4 (рабочая бета) - выпущена, есть она официальном сайте<br />
* версия для тестов сообществом 0.45-альфа - распространяется через телеграмм канала t.me/perfolenta <br />
** выпущен функциональный язык программирования [[Перфо]] Альфа версия написанный на Перфолента.NET<br />
* версия с 0.5 - будет доделан редактор форм - В разработке.<br />
<br />
== Документация==<br />
* [[Описание языка Перфолента.NET]] (на основе официального, дополняйте)<br />
** [[Объектно-ориентированное программирование на языке Перфолента.NET]]<br />
** [[Многозадачность и многопоточность в языке Перфолента.Net]]<br />
** [[Оператор Попытка. Структурная обработка ошибок.]] - модульное (Unit) тестирование<br />
* [[Перфолента.Net - ЧаВО]]<br />
* [[Описание языка Перфолента.NET для программистов]] - Если есть возможность дополните<br />
* [[Учебник по языку Перфолента.NET]] - в разработке<br />
* [[Скрипты и программы на языке Перфолента.NET]] - Наполняйте!<br />
<br />
== Совместимость ==<br />
Перфолента.NET совместима с языками написанными на .NET (VisualBasic.NET и C#) и с 1С подобными язками [[1С:Предприятие]], [[OneScript]] и [[РусФокс]].<br />
<br />
IDE Перфолента.NET может также использоваться для написания кода на [[1С Скрипт]] и [[РусФокс]].<br />
<br />
== См. также ==<br />
* [[1С Скрипт]]<br />
* [[РусФокс]]<br />
* [[Гонец (язык программирования)]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
* https://t.me/perfolenta - официальный телеграмм канал<br />
* https://vk.com/perfolenta_net Сообщество пользователей во Вконтакте<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Удалено из википедии]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8030Перфолента.NET2020-07-28T06:45:06Z<p>Дизайнер: </p>
<hr />
<div>'''Перфолента.Net''' - объектно ориентированный язык программирования с русскоязычным синтаксисом 1С. Работает под Windows 7/10 на платформе .NET. Имеет строгую и динамическую типизацию. Текущая версия 0.45<br />
<br />
[[Файл:Перфолента.NET.jpg|мини|слева|Логотип Перфолента.NET]]<br />
<br />
Пытаться создать статью о Перфолента.NET в википедии не имеет смысла - удаляется в течении 1 часа без обсуждения.<br />
<br />
== Версии ==<br />
* Текущая версия 0.4(рабочая бета) - выпущена, есть она официальном сайте<br />
* версия для тестов сообществом 0.45-альфа - распространяется через телеграмм канала t.me/perfolenta <br />
* версия с 0.5 - будет доделан редактор форм - В разработке.<br />
<br />
== Документация==<br />
* [[Описание языка Перфолента.NET]] (официальное)<br />
* [[Перфолента.Net - ЧаВО]]<br />
* [[Описание языка Перфолента.NET для программистов]]<br />
* [[Учебник по языку Перфолента.NET]]<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
== Совместимость ==<br />
Перфолента.NET совместима с языками написанными на .NET (VisualBasic.NET и C#) и с 1С подобными язками [[1С:Предприятие]], [[OneScript]] и [[РусФокс]].<br />
<br />
IDE Перфолента.NET может также использоваться для написания кода на [[1С Скрипт]] и [[РусФокс]].<br />
<br />
== См. также ==<br />
* [[1С Скрипт]]<br />
* [[РусФокс]]<br />
* [[Гонец (язык программирования)]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
* https://t.me/perfolenta - официальный телеграмм канал<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Удалено из википедии]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8029Перфолента.NET2020-07-28T06:44:51Z<p>Дизайнер: </p>
<hr />
<div>'''Перфолента.Net''' - объектно ориентированный язык программирования с русскоязычным синтаксисом 1С. Работает под Windows 7/10 на платформе .NET. Имеет строгую и динамическую типизацию. Текущая версия 0.45<br />
<br />
[[Файл:Перфолента.NET.jpg|мини|слева|Логотип Перфолента.NET]]. <br />
<br />
Пытаться создать статью о Перфолента.NET в википедии не имеет смысла - удаляется в течении 1 часа без обсуждения.<br />
<br />
== Версии ==<br />
* Текущая версия 0.4(рабочая бета) - выпущена, есть она официальном сайте<br />
* версия для тестов сообществом 0.45-альфа - распространяется через телеграмм канала t.me/perfolenta <br />
* версия с 0.5 - будет доделан редактор форм - В разработке.<br />
<br />
== Документация==<br />
* [[Описание языка Перфолента.NET]] (официальное)<br />
* [[Перфолента.Net - ЧаВО]]<br />
* [[Описание языка Перфолента.NET для программистов]]<br />
* [[Учебник по языку Перфолента.NET]]<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
== Совместимость ==<br />
Перфолента.NET совместима с языками написанными на .NET (VisualBasic.NET и C#) и с 1С подобными язками [[1С:Предприятие]], [[OneScript]] и [[РусФокс]].<br />
<br />
IDE Перфолента.NET может также использоваться для написания кода на [[1С Скрипт]] и [[РусФокс]].<br />
<br />
== См. также ==<br />
* [[1С Скрипт]]<br />
* [[РусФокс]]<br />
* [[Гонец (язык программирования)]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
* https://t.me/perfolenta - официальный телеграмм канал<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Удалено из википедии]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8028Перфолента.NET2020-07-28T06:43:20Z<p>Дизайнер: </p>
<hr />
<div>'''Перфолента.Net''' - объектно ориентированный язык программирования с синтаксисом 1С. Работает под Windows 7/10 на платформе .NET Имеет строгую и динамическую типизацию.<br />
[[Файл:Перфолента.NET.jpg|мини|слева|Логотип Перфолента.NET]]. <br />
<br />
Пытаться создать статью о Перфолента.NET в википедии не имеет смысла - удаляется в течении 1 часа без обсуждения.<br />
<br />
== Версии ==<br />
* Текущая версия 0.4(рабочая бета) - выпущена, есть она официальном сайте<br />
* версия для тестов сообществом 0.45-альфа - распространяется через телеграмм канала t.me/perfolenta <br />
* версия с 0.5 - будет доделан редактор форм - В разработке.<br />
<br />
== Документация==<br />
* [[Описание языка Перфолента.NET]] (официальное)<br />
* [[Перфолента.Net - ЧаВО]]<br />
* [[Описание языка Перфолента.NET для программистов]]<br />
* [[Учебник по языку Перфолента.NET]]<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
== Совместимость ==<br />
Перфолента.NET совместима с языками написанными на .NET (VisualBasic.NET и C#) и с 1С подобными язками [[1С:Предприятие]], [[OneScript]] и [[РусФокс]].<br />
<br />
IDE Перфолента.NET может также использоваться для написания кода на [[1С Скрипт]] и [[РусФокс]].<br />
<br />
== См. также ==<br />
* [[1С Скрипт]]<br />
* [[РусФокс]]<br />
* [[Гонец (язык программирования)]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
* https://t.me/perfolenta - официальный телеграмм канал<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]<br />
[[Категория:Удалено из википедии]]</div>Дизайнерhttps://xn--80ac3cm.xn--p1ai/index.php?title=%D0%9F%D0%B5%D1%80%D1%84%D0%BE%D0%BB%D0%B5%D0%BD%D1%82%D0%B0.NET&diff=8027Перфолента.NET2020-07-28T06:39:15Z<p>Дизайнер: /* Совместимость */</p>
<hr />
<div>'''Перфолента.Net''' - объектно ориентированный язык программирования с синтаксисом 1С. Работает под Windows 7/10 на платформе .NET Имеет строгую и динамическую типизацию.<br />
[[Файл:Перфолента.NET.jpg|мини|слева|Логотип Перфолента.NET]]. <br />
<br />
== Версии ==<br />
* Текущая версия 0.4(рабочая бета) - выпущена, есть она официальном сайте<br />
* версия для тестов сообществом 0.45-альфа - распространяется через телеграмм канала t.me/perfolenta <br />
* версия с 0.5 - будет доделан редактор форм - В разработке.<br />
<br />
== Документация==<br />
* [[Описание языка Перфолента.NET]] (официальное)<br />
* [[Перфолента.Net - ЧаВО]]<br />
* [[Описание языка Перфолента.NET для программистов]]<br />
* [[Учебник по языку Перфолента.NET]]<br />
* [[Скрипты и программы на языке Перфолента.NET]]<br />
<br />
== Совместимость ==<br />
Перфолента.NET совместима с языками написанными на .NET (VisualBasic.NET и C#) и с 1С подобными язками [[1С:Предприятие]], [[OneScript]] и [[РусФокс]].<br />
<br />
IDE Перфолента.NET может также использоваться для написания кода на [[1С Скрипт]] и [[РусФокс]].<br />
<br />
== См. также ==<br />
* [[1С Скрипт]]<br />
* [[РусФокс]]<br />
* [[Гонец (язык программирования)]]<br />
<br />
== Ссылки ==<br />
* http://promcod.com.ua/cat.asp?cat=perfolenta-programmig-language Официальная страница<br />
* https://t.me/perfolenta - официальный телеграмм канал<br />
<br />
[[Категория:Язык программирования]]<br />
[[Категория:Язык программирования с русским синтаксисом]]<br />
[[Категория:Язык программирования с синтаксисом 1С]]<br />
[[Категория:Перфолента.NET]]</div>Дизайнер