1С+Классы. Версия-0

28.10.16

Разработка - Разработка внешних компонент

Разработано ООП-расширение языка 1С, включающее (но не ограничивающееся): Классы как абстрактные типы данных с элементами «переменная», «свойство», «функция», «процедура»; Интерфейсы как абстрактные классы без элементов состояния («переменная») и без привязки к реализации методов (свойств, процедур, функций) при определении; Имплементация (реализация) интерфейсов классами; - одиночное открытое наследование; Области видимости «внутренняя» (private), «экспорт» (public), «защищенная» (protected); Статические элементы классов (общие для всех экземпляров класса); Замещение (переопределение реализации) методов при наследовании – «виртуальные методы, свойства»; Сокрытие (затенение) обычных (не замещаемых) элементов при наследовании; Перегрузка процедур и функций по количеству и типам данных аргументов; Конструкторы класса; Деструктор класса; Слабые ссылки; Делегаты.

Скачать файлы

Наименование Файл Версия Размер
Компонента escls83.dll и демо конфигурация
.zip 142,99Kb
7
.zip 142,99Kb 7 Скачать

Компонента представленная в этой статье привносит в 1С возможность определять сущности вида:

Класс Машинка
	Функция ДайКоличествоКолес(), Абстрактная
КонецКласса

Класс МашинкаЛегковая Наследует Машинка
	Функция ДайКоличествоКолес(), Замещает
КонецКласса

Класс МашинкаБТР87
Внутр:
	Перем м_колКолес;
Экспорт:
	Функция ДайКоличествоКолес(), Замещает
КонецКласса

И в обычном модуле 1С (привязка реализации методов):

Функция МашинкаЛегковая_ДайКоличествоКолес(Знач ЭтотКласс) Экспорт
	Возврат 4;
КонецФункции
Функция МашинкаБТР87_ДайКоличествоКолес(Знач ЭтотКласс) Экспорт
	Возврат ЭтотКласс.м_колКолес;
КонецФункции

Далее возможно эти сущности создавать и оперировать ими как обычными объектными значениями 1С.

Т.е. обычные и привычные в других языках программирования классы. Синтаксис выбран соответствующий духу Бейсика и более всего похож на vb.net от Microsoft. Реализация также каноническая и претендующая на соответствие возможностям vb.net, c# или java.

Но это пока черновик (или версия-0) только ограниченно демонстрирующая эту технологию. Пример в демонстрационной конфигурации в конце этой статьи выбран не удачно. А некоторые недоработки и неприспособленность редактора текста модуля 1С к этой функциональности превращают код в чудовищную кашу. Поэтому из самой статьи этот код я убрал. По свидетельству немногочисленных выживших после увиденного «ЭТО вызывает быстротечный ООП головного мозга с неминуемым взрывом последнего». Ситуация изучается.

На словах. Код в конфигурации является некоторой переработкой шуточной программы <Hello World Enterprise Edition> на java. Т.е. он демонстрирует не просто ООП, а наихудшее его enterprise проявление. Поэтому даже название модуля сокращено до двусмысленности – ОопХелл. Собственно если это и демонстрационная программ, то точно не для первой статьи. На этом примере автор отлаживал и хотел продемонстрировать возможности компоненты в использования ООП-техник известных как <паттерны проектирования>. Также можно почитать у «заклятых друзей» - <Паттерны проектирования в ABAP примерах>. В общем – выглядит это пока чудовищно, но работает.

Тем кто просто пока интересуется «Что за зверь такой ООП?» я бы не рекомендовал скачивать и разбираться в версии-0. Даже из любопытства не всем нужно смотреть как делается колбаса. Можно ведь и заработать стойкое отвращение к этому вполне полезному и обыденному продукту. Более правильным будет почитать литературу и поиграться с vb.net или java. Если эта технология получит развитие, то здесь будет тоже самое или очень близкое.

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

Отдельно ожидающим простоты и легкости кода типовых конфигураций. Разработчики проделали гигантскую работу убрав все сложности под капот платформы. И убрали они туда в том числе и ООП. ООП это инструмент для решения больших и сложных проблем. Простым он не будет никогда. Не бывает простых решений сложных проблем. В пределах возможностей читабельность кода повышать можно, но концептуальная легкость и простота с ООП не совместима.

Немного относительно самого ООП, хотя это не дискуссионная статья об ООП. Статью об ООП я только планирую. Проблематика ООП применительно к 1С корнями будет восходить к вопросам «Что есть решения от 1С или аналогичные продукты: это системы учета или управленческие инструменты?» и приземленней к 1С «Это программа (пул программ) или среда\платформа их разработки». Эти вопросы сами по себе масштабны и дискуссионны. Они не имеют единого ответа. Отвечая на них, человек скорее выбирает его и только его мировоззренческую позицию и эта позиция во многом определит его отношение к ООП. А сам по себе ООП это просто инструмент. Со своими преимуществами и недостатками. Инструмент для профессионалов.

Итак. Всех кто еще не испугался, не заснул и не переключился на что-нибудь полезное прошу за мной дальше.

	ОопХелл.Подключить();
	ОопХелл.Здрасьте();

Кусочек ужаса из демки:

Функция _Класс_ФабрикаАгентов_()
	Возврат ""
	"Класс ФабрикаАгентов"
	"ВНУТР:"
	"	Конструктор() 					:= ФабрикаАгентов_Конструктор"
	"ВНУТР:"
	"	Перем м_фабрика, 		СТАТИК"
	"	Перем м_стдАгент"
	"ЭКСПОРТ:"
	"	Свойство Фабрика,	 	СТАТИК									ЧТЕНИЕ 	:= ФабрикаАгентов_Объект"
	"ЭКСПОРТ:"
	"	Свойство СтандартныйАгент 										ЧТЕНИЕ 	:= ФабрикаАгентов_СтандартныйАгент"
	"	Функция СделайАгента(имя_ Как Строка)  ПЕРЕГРУЗКА 						:= ФабрикаАгентов_СделайАгентаС"
	"	Функция СделайАгента(имя_ Как Строка, язык_ Как Строка)  ПЕРЕГРУЗКА 	:= ФабрикаАгентов_СделайАгентаСС"
	"КонецКласса"
КонецФункции
...
Функция 	Агент_Поздоровайся(знач ЭтотКласс, другой_) Экспорт
	Перем рез;
	Перем другой_агент;
	Перем другой_агент_неверб;
	
	Попытка
		другой_агент = другой_.ДайИнтерфейс("Агент");
	Исключение
	КонецПопытки;
	Если другой_агент = Неопределено Тогда
		Возврат СС.РезультатыМенеджер.Результат_Не_неАгент;		
	КонецЕсли;
	
	Если другой_агент = ЭтотКласс.ДайИнтерфейс("Агент") тогда
		Возврат СС.РезультатыМенеджер.Результат_Ок_сСобой;		
	КонецЕсли;
	
	рез = другой_агент.ПримиСообщение(ЭтотКласс.МоеЗдрасьте);
	Если не рез.Успех тогда
		если рез = СС.РезультатыМенеджер.Результат_не_неПонял и ЭтотКласс.м_язык_другой <> Неопределено Тогда
			рез = другой_агент.ПримиСообщение(СС.ФабрикаЗдрасьте.СделайЗдрасьте(ЭтотКласс.м_язык_другой));
			Если рез = СС.РезультатыМенеджер.Результат_ок Тогда
				рез = СС.РезультатыМенеджер.Результат_ок_сПереводом;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если не рез.Успех тогда
		другой_агент_неверб = другой_агент.ДайИнтерфейс("НевербальнаяКоммуникация");
		если другой_агент_неверб <> Неопределено тогда
			рез = другой_агент_неверб.ПримиСообщение(СС.ФабрикаЗдрасьте.СделайЗдрасьтеЖест());
			Если рез = СС.РезультатыМенеджер.Результат_ок Тогда
				рез = СС.РезультатыМенеджер.Результат_Ок_Невербально;
			КонецЕсли;			
		КонецЕсли;
	КонецЕсли;
	
	Возврат рез;
КонецФункции

По сути. Это пререлиз, черновик или версия 0. Т.е. сыровато, но сама технология, на мой взгляд, уже заслуживает публикации. Целью этой статьи является окончательно определиться с синтаксисом, поговорить, очертить границы и наметить план доработок. Особенно меня волнует синтаксис – его переделки наиболее болезненны. Также, несомненно, будут ошибки, и я буду очень благодарен, если мне на них укажут.

Техническое

            Сразу. Версия-0: Количество аргументов методов ограничено 16. Значения по умолчанию для аргументов методов не поддерживаются. Объекты компоненты не поддерживают сериализацию. Коллекции 1С не поддерживаются. Обработка ошибок в зачаточном состоянии и малоинформативна, ассерты выведены в релиз. Течи памяти не проверял. Это черновик.

            Компонента откомпилирована VS2015 для win32 (v140_xp, статическая линковка). Работаю я на win7-32 и тестирую (на данный момент) в 1С:Предприятие 8.3.6.2363. Все остальное в этой версии не пробовал. Ранее, в процессе экспериментов, были VS2010, Win2kSrv32 и платформы начиная с 8.3.4.365. Буду признателен, если кто подскажет типовые конфигурации которые стоит тестировать, а то все и везде это слишком много.

            Все реализовано поверх родных интерфейсов 1С без какого-либо вмешательства в исходный код платформы. Связность с системой минимальна. Пул памяти 1С не используется. В системе объектов платформы не регистрируюсь, создать объекты компоненты можно только методами компоненты (Новый … - нельзя). Версия-0: своих ТИПов в систему также не добавляю, а мимикрирую под ФиксированнаяСтруктура. Моим типам платформа пока в отладочном табло свойства не разворачивает и это неудобно.

            Стоимость экземпляра простейшего класса sizeof(long) + 3*sizeof(uintptr_t). Стоимость определителя класса не считал, но тяжелый. Стоимость каждого унаследованного или имплементированного интерфейса 3*sizeof(uintptr_t). Возможно доработать до 2*sizeof(uintptr_t) для простых классов. Стоимость вызова 1-2 virtual call. Переаллокация аргументов производится на стеке. Оценка быстродействия есть в демонстрационной конфигурации и здесь обсуждать ее считаю нецелесообразным. Затраты есть. Есть чуть резервов. На данном этапе  и для данного типа приложения неважно.

            Все объекты компоненты (и 1С) являются СОМ-объектам и время их жизни определяется их счетчиком ссылок. Соответственно все (за исключением синглетонов) подвержены <проблеме циклических ссылок>. Компонента никоим образом не контролирует это. Экземпляр класса уничтожается тогда, когда освобождены все ссылки на все его объекты-интерфейсы. Или зависает в памяти до завершения приложения, если прямо или опосредовано в его переменной сохранили его же самого. Определители классов – не синглетоны (версия 0). Объекты созданные компонентой нельзя сохранять в переменных модуля приложения без очистки этих переменных ПриЗавершенииРаботыСистемы(), или еще как. 1С выгружает компоненту до очистки переменных и попытка очистки переменных содержащих объекты созданные компонентой приводит к краху. По возможности нигде и никогда не используйте глобальные переменные.

            Классы задаются текстовыми строками. Можно провести аналогию с реализацией SQL в 1С, которая тоже не является частью языка и в текстовом виде передается некоему механизму. Только SQL манипулирует данными, а escls манипулирует кодом. Механизм reflection в версии-0 не предусмотрен.

Несколько общих моментов

            Делая это, я держал в голове некоторую концепцию «лингвистически корректного и академически правильного национального Бейсика». Поэтому «КлассДитя» НАСЛЕДУЕТ «КлассПапа». Наследует, а не расширяет, дополняет, углубляет, уточняет или еще как. Также можно писать «Свойство ... ЗАМЕЩАЕМОЕ», а «Метод ... ЗАМЕЩАЕМЫЙ» (версия-0: можно и наоборот – я все-таки не школьное сочинение проверяю).

            Также считаю правильным, что класс определяется, а не описывается, декларируется или еще как. Название виртуальных методов замещаемыми тоже считаю правильным, поскольку без отсылок к истории и техническим деталям объяснить неподготовленному человеку в чем виртуальность не представляется возможным.

            В моем понимании Бейсик – язык в первую очередь дружелюбный, а многословность его это обратная сторона дружелюбности и, иногда, необходимое зло. Сравните: «Асс Фуу(Баз Бар)»; и «Функция Фуу(Бар Типа Баз) Возвращает Асс». Обе конструкции концептуально, с учетом особенностей человеческого мышления, верны. Только они подходят к решению задачи с разных сторон.

            Дружелюбность языка не означает его неполноценность. За критерий полноценности языка выбрана возможность выражения с его использованием общепринятой в программной индустрии концепции <паттернов программирования>.

            Учет принципа разделения разработки. В иерархии наследования у каждого класса по умолчанию разные разработчики. Задача языка помочь каждому разработчику «дать» то что он хочет дать,  и «не давать» ничего явно не указанного. В частности поэтому при трехуровневом наследовании конструкция «ЭтотКласс.БазовыйКласс.БазовыйКласс...» работать не будет. Разработчик «среднего» класса должен явно дать доступ своему наследнику к некоторой функциональности своего базового класса.

            ООП – это зло, но ООМ (объектно-ориентированное мышление) -  это добро. Добро невозможно без зла и единственный путь здесь – это сделать зло дружелюбным.

Документация

            Объект класс – это совокупность объектов-интерфейсов класса. Объект-интерфейс класса создается компонентой и распознаются платформой как допустимое объектное значение. Его можно сохранять в переменные, передавать параметром, и т.д. В случае, если класс имеет секцию внутренних данных и\или методов, то компонентой создается два объекта-интерфейса класса. Один публичный – его возвращает метод .СоздатьКласс(), а другой приватный – его получают в качестве первого параметра методы реализации. Имя класса это также и имя публичного объекта-интерфейса класса. Если класс наследует другой класс, то у него будет уже четыре объекта-интерфейса – публичный\внутренний базового плюс публичный\внутренний самого класса. Если у базового класса есть защищенные элементы (не доступные публично, но доступные наследнику), то у него создается еще один внутренний объект-интерфейс возвращаемый свойством .МойБазовый внутреннего объекта-интерфейса класса наследника.  Если класс реализует (имплементирует) интерфейс, то у него будет создан еще один именованный объект-интерфейс. И так далее. Все объекты-интерфейсы класса дают доступ строго только к определенным для них элементам класса. Объект-интерфейс базового класса (.МойБазовый ) содержит варианты элементов до переопределения их наследником. Все объекты-интерфейсы класса имеют функцию .ДайИнтерфейс(ИмяИнтерфейса), которая возвращает соответствующий объект-интерфейс или неопределенно. Любой внутренний интерфейс получить способом .ДайИнтерфейс(…) нельзя. Все свойства и методы объектов-интерфейсов реализуют свою функциональность путем вызова методов объектов платформы заданных при определении класса.

            Собственно ИНТЕРФЕЙС это специальная форма класса у которого не может быть переменных, все свойства и методы (процедуры и функции) замещаемые и без указания реализации - АБСТРАКТНЫЕ. Т.е. голая декларация метаданных некоторого контекста смысл обретающая тогда, когда класс этот ИНТЕРФЕЙС реализует.

            В дальнейшем, для обозначения объекта-интерфейса класса я буду использовать принятый в 1С термин «контекст» для исключения путаницы с принятом в программировании термином ИНТЕРФЕЙС.

Сам объект компоненты содержит методы:

Функция ОпределитьКласс(ТекстОпределения, ОбъектРеализации)            - создает, внутренне регистрирует и возвращает объект ОпределительКласса. В ТекстеОпределения может быть более одного определения класса и\или интерфейса. Возвращается внутренний интерфейс объекта ОпределительКласса последнего определения.

Функция СоздатьДелегат(Объект, ИмяМетода) – создает объект Делегат. Этот объект имеет только один не именованный (версия-0) метод, при вызове которого, он вызывает заданный при его создании метод заданного объекта. Делегирует вызов. Тип метода (процедура или функция), а также аргументы определяются автоматически. Не именованный означает что вызвать его можно с любым именем - <делегат>.Вызвать(…) /.Выпонить(…) /.Провести(…) /.ДелайЧтоДолженБудьЧтоБудет(…) и т.д. Делегатов к свойствам и делегатов с привязкой аргументов в версии-0 нет.

Свойство СоздатьКласс – возвращает объект с динамически, по мере определения классов с публичными конструкторами, расширяемым набором методов с именами определяемых классов. Сигнатуры методов соответствуют сигнатурам определенных для класса конструкторов. Для использования в семантике <имя-переменной-компоненты>.СоздатьКласс.<имя-класса>(<аргументы-конструктора>).

Также, по мере определения классов, к объекту компоненты динамически добавляется свойства с именами классов возвращающие публичные интерфейсы объектов-определителей классов (объектов-определителей интерфейсов).

Свойство ПустаяСсылка – возвращает предопределенный в компоненте объект  ПустаяСсылка (см. Деструктор)

Функция ДайТики()   - версия-0, в тестовых целях возвращает GetTickCount()

            Класс определяется методом компоненты .ОпределитьКласс(ТекстОпределения, ОбъектРеализации). Определение класса задается в текстовом виде через параметр ТекстОпределения. Через параметр ОбъектРеализации передается любой допустимый в 1С объект имеющий методы указанные в ТекстеОпределения класса в качестве привязки к реализации элементов класса. Первым параметром метода реализации должен быть параметр по-значению, в который компонента передает внутренний контекст реализуемого объекта.

            Элементы класса – переменная, свойство, функция, процедура. Свойства и переменные не отличаются по способу обращения к ним через интерфейс класса – синтаксис свойства 1С. Но сами значения в случае переменных хранятся в самом экземпляре класса (или экземпляре определителя класса), а в случае свойств происходит обращение к методам платформы указанным в привязках реализации. Типы данных переменных – любые допустимые в 1С (а по сути любые COM-объекты). При создании все переменные принудительно  получают значение 1С::неопределенно, а при уничтожении объекта принудительно очищаются (.Release()).

Общие элементы описания синтаксиса

            В квадратных скобках [] опциональные параметры. Языковые конструкции в угловых скобках <>. Варианты в виде (<вариант-1> | <вариант-2>). БОЛЬШИМИ буквами термины. Термин это последовательность символов распознаваемая парсером как единое целое. На данный момент термины двуязычны ru\en. Термин КЛАСС означает строку Класс или Class. Регистр символов значения не имеет. Термины могут быть многовариантными – н.р. КАК предваряющий тип параметра или переменной представляется строками As, Как, Есть, Это, Типа. Еще раз – это черновик - возможно что-то лишнее, а чего-то не хватает

Точка с запятой в конце строки определения элемента опциональна. Переход на новую строку игнорируется.

Имена элементов (далее <имя>)

<имя> - это имя элемента в соответствии с соглашением о именовании 1С. Первый символ или буква или ‘_’ далее буквы и цифры в любой последовательности. Регистр символов игнорируется.

            Многоязычность в версии-0 не поддерживается. Только грамматика в части терминов двуязычна (ru\en). Многоязычность имен впоследствии предполагается реализовывать с помощью специальных атрибутов. Например: [&EN = ClassFoo] КЛАСС КлассФуу.

            На даный момент запрещается определять свойства (и переменные) с именами совпадающими с именами методов и наоборот. см.<задумано-но-не-сделано>::<элементы-по-умолчанию>

            Запрещается определять свойства и методы с именами совпадающими с именами предопределенных элементов – н.р. СоздатьКласс, МойБазовый, Конструктор и т.д.

            PS: Далее по тексту может встречаться <идентификатор>. В исходном BNF это <имя>.<имя>…<имя>. В версии-0 не поддерживается и читайте просто <имя>.

Привязка к реализации (далее <привязка>)

            Указание привязки к реализации для методов (функций и процедур) передается в строке определения в виде ... := <имя>. Это <имя> ищется у ОбъектаПлатформы и проверяется на соответствие соглашению о формате.

Функции и процедуры указанные в привязках должны иметь вид:

ФУНКЦИЯ <имя>(ЗНАЧ <класс> [, <остальные-параметры-если-есть>])

или

ПРОЦЕДУРА <имя>(ЗНАЧ <класс> [, <остальные-параметры-если-есть>])

Для свойств указание на привязку к реализацию задается в виде:

ЧТЕНИЕ := <имя-функции-чтения> ЗАПИСЬ := <имя-процедуры-записи>.

Функция чтения свойства должна иметь вид ФУНУЦИЯ <имя> (ЗНАЧ <класс>) и возвращать значение свойства.

Процедура записи должна иметь вид ПРОЦЕДУРА <имя> (ЗНАЧ <класс>, НовоеЗначениеСвойства). В параметр НовоеЗначениеСвойства передается значение, которое присваивается свойству в программе.

Одно из указаний на реализацию может быть опущено. Если не указано ЗАПИСЬ, то свойство становится ТолькоДляЧтения. Если не указано ЧТЕНИЕ, то свойство становится ТолькоДляЗаписи. Опускание и ЧТЕНИЕ и ЗАПИСЬ не допускается.

            При вызове нестатических свойств и методов компонента в аргумент <класс> помещает внутренний контекст объекта экземпляра класса – ЭтотКласс.

            При вызове статических свойств и методов в аргумент <класс> компонента помещает внутренний контекст объекта определителя класса – МойОпределитель.

            Для абстрактных свойств и методов (помеченных атрибутом АБСТРАКТН(АЯ|ОЕ)) указание привязки недопустимо. Для абстрактных свойств допустимо указывать атрибуты ТолькоЧтение\ТолькоЗапись. Если атрибут опущен, то свойство считается доступным и для чтения и для записи. При задании привязки к реализации в классе наследнике допустимо указывать только привязку разрешенную атрибутом <только-чтение-запись> абстрактного свойства.

            PS: В текущей реализации ЭтотКласс и МойОпределитель это, конечно, просто имена переменных и могут быть любыми. Но настоятельно рекомендую использовать именно эти термины. Хотя это и близко к невозможному (а скорее очень трудоемко), но нельзя исключать, что в будущем они станут терминами языка. PPS: сами термины обсуждаемы, но рекомендация унификации остается.

Общее описание атрибутов

            Атрибут СТАТИК означает, что элемент с этим атрибутом един для всех экземпляров этого класса и не имеет доступа к данным экземпляра класса, а только к таким же статическим элементам класса. По сути, статический элемент - это элемент объекта определителя класса, но присутствует и в контекстах экземпляра класса. В методы реализации статических элементов указанные в привязке первым параметром передается внутренний интерфейс определителя класса, а не внутренний интерфейс экземпляра класса. Таким образом статические элементы имеют доступ к другим статическим элементам класса, но не к элементам экземпляра класса. Публичные статик элементы доступны через обращение к определителю класса через объект компоненты. Совпадающие по определению статические свойства и методы наследника скрывают свойства и методы базового в контексте наследника.

Версия-0: первичная инициализация статических переменных не реализована. После создания объекта-определителя класса, функция компоненты ОпределитьКласс(…) возвращает приватный интерфейс определителя давая возможность провести первичную инициализацию внутренних статических переменных, если это необходимо.

            Атрибут ПЕРЕГРУЗКА применим к функциям и процедурам и означает создание более одного метода с одинаковым именем, но отличающихся количеством и\или типом данных аргументов. При вызове метода класс, на основании количества и фактического типа данных переданных параметров, переадресует вызов соответствующему методу реализации. Поддерживаются типы данных платформы ЧИСЛО, СТРОКА, ДАТА, БУЛЕВО, НЕОПРЕДЕЛЕНО, NULL, ТИП, ОБЪЕКТ. Также может быть использован термин ЛЮБОЕ, означающий что данный аргумент метода может принимать значение любого типа. Если тип не указан, то считается ЛЮБОЕ. Согласованность всего букета перегрузок проверяется для недопущения неоднозначного поведения. Атрибут ПЕРЕГРУЗКА обязательно явно использовать во всех вариантах метода, даже если он один, но вы допускаете его перегрузку у наследников. Атрибут трактуется как атрибут имени.

            При сокрытии или замещении букета перегрузок из базового класса в наследнике всегда скрывается весь букет. Приоритет имени. Для «проявления» перегрузок из базового класса в наследнике их нужно явно определять. Версия-0: конструкция ИСПОЛЬЗОВАТЬ <…> не поддерживается.

            Ограничение методики: Интерфейсы 1С не поддерживают концепцию перегрузки методов. Перегрузка реализована компонентой с использованием особенностей работы со значениями по умолчанию. Поэтому использование значений по умолчанию для последних, непересекающихся с остальными вариантами, аргументов принципиально невозможна. Для пересекающейся части аргументов возможна, но только одинаково для всех вариантов. Пример: Фуу(а1_) ПЕРЕГРУЗКА; Фуу(а1_, а2_) ПЕРЕГРУЗКА. Для а2_ значения по умолчанию невозможны. Для а1_ возможны, но только одинаково у всех вариантов.

            Ограничения версии-0: а) Количество аргументов – 16. б) Алгоритм проверки согласованности, если указано ЛЮБОЕ, исключает другие типы данных по данному параметру, а не дополняет существующие.

            Атрибуты замещения ЗАМЕЩАЕМ[АЯ|ОЕ], ЗАМЕЩАЕТ, ЗАМЕЩАТьОБЯЗАТЕЛЬНО, НеЗАМЕЩАТЬ, АБСТРАКТН[АЯ|ОЕ] . Определяют замещаемый (виртуальный) метод или свойство. Реализация указанная в наследнике замещает реализацию указанную у базовых классов. Таким образом реализация свойства или метода у класса единственна и определяется наследноком. Для абстрактного метода\свойства реализация не указывается. Вызов абстрактного метода приводит к ошибке исполнения. В остальных случаях реализация должна быть указана обязательно. При определении интерфейса указывать атрибут абстрактности обязательно. Просто атрибут ЗАМЕЩАЕМ[АЯ|ОЕ] определяет метод как замещаемый и проводит процедуру замещение неуспех которой не является ошибкой. ЗАМЕЩАЕТ требует чтобы метод обязательно заместил что-либо или ошибка. ЗАМЕЩАТьОБЯЗАТЕЛЬНО указывет, что при определении наследника класса он должен обязательно заместить этот метод своей реализацией. НеЗАМЕЩАТЬ, наоборот, запрещает замещать данный метод наследниками. Возможно сочетание атрибутов – Замещает НеЗамещать, Замещает ЗамещатьОбязательно.

            При указании атрибута АБСТРАКТН[АЯ|ОЕ] указание привязки к реализации считается ошибкой.

Версия-0: При создании экземпляра класса наличие не реализованный абстрактных элементов не контролируется. При вызове свойства или метода без реализации выбрасывается ошибка.

            Если метод или свойство не имеет атрибутов СТАТИК или атрибутов замещения, то он считается ОБЫЧНЫМ (или скрываемым) методом экземпляра класса. Метод указанный у наследника скрывает собой метод базового класса в контексте наследника, но не замещает его в контексте базового класса. Если имя метода определяет букет перегрузок, то скрыты будут все перегруженные методы.

(версия-0: напрашиваются атрибуты НеСкрывать\СкрыватьОбязательно)

Области видимости элемента (далее <область>)

Область видимости (ВНУТР | ЗАЩИЩ[(Е|Ё)Н] | ЭКСПОРТ) влияет на присутствие элементов в контекстах класса:

 - Публичная (термин ЭКСПОРТ) – элемент виден всем всегда и во всех контекстах.

 - Внутренняя (термин ВНУТР) – элемент виден только через внутренний контекст ЭтотКласс

 - Защищенная (термин ЗАЩИЩ(Е|Ё)Н) – элемент виден этому классу и его наследникам, но не через публичный контекст. Т.е. унаследовано присутствуют в контексте ЭтотКласс наследника и непосредственно в контексте возвращаемом свойством МойБазовый.

Может задаваться как секцией так и атрибутом определения элемента (версия-0: склоняюсь атрибут убрать и оставить только секции, т.к. может приводить к путанице. Или сделать атрибуты опцией языка.).

Имя секции задается термином области видимости с двоеточием в конце. Область видимости заданная атрибутом элемента имеет приоритет перед заданной секцией. По умолчанию, с начала определения класса секция устанавливается в ЭКСПОРТ.

Область видимости – это для точки вызова. Не для компилятора. Компилятор «видит» все. Заместить внутренний замещаемый элемент базового класса из производного можно, а вызвать нельзя.

Синтаксис строк определения элементов

Общий вид строки определения элемента: <определение-…> [,] <атрибуты-определения> [:= <привязка>] [;]

<определение-начало-класса>

            [<атрибуты-класса>] КЛАСС <имя-класса> [НАСЛЕДУЕТ <идентификатор>]

Наследование сделано не прототипно. Т.е. базовый класс как самостоятельный объект «там» нигде не существует. В терминах 1С при объявлении базового класса происходит начальная инициализация «метаданных» класса «метаданными» базового класса. На данный момент наследование сделано одиночным (т.е. можно унаследоваться только от одного класса) и только публичным (т.е. все публичные методы базового класса становятся доступны через публичный интерфейс производного класса, в версии-0 изменение области видимости элементов не поддерживается). В принципе, применяемая модель позволяет делать и закрытое, и множественное и даже множественное виртуальное наследование.

<атрибуты-класса>

ДляНАСЛЕДОВАНИЯ – запрещает создание экземпляра класса. От такого класса можно только наследоваться.

НеНАСЛЕДУЕМЫЙ – от такого класса запрещено наследование.

<определение-конец-класса>

            КОНЕцКЛАССА

            В теле определения класса должно быть определение хотя бы одного элемента класса. Пустые классы не допускаются.

<определение-начало-интерфейса>

            [<атрибуты-интерфейса>] ИНТЕРФЕЙС <имя> [НАСЛЕДУЕТ <имя>]

Допустимо вне тела другого определения. Версия-0: Вложенные определения не поддерживаются. Трактуется как начало определения нового интерфейса и до определения КонецИнтерфейса могут быть только декларации свойств, функций и методов. Указание атрибута АБСТРАКТН[АЯ|ОЕ] для элементов интерфейса обязательно. Элементами интерфейса могут быть только свойства, функции и процедуры. Переменные в интерфейсе недопустимы.

<атрибуты-интерфейса> не предусмотрены.

<определение-конец-интерфейса>

            КОНЕцИНТЕРФЕЙСА

Обозначает конец определения объекта интерфейс или конец секции реализации интерфейса внутри класса. В случае конца определения интерфейса контролируется определения хотя бы одного элемента – пустые интерфейсы не допускаются (версия-0: надо разрешить).  В случае конца секции реализации интерфейса полнота реализации не контролируется – допустимо реализовать интерфейс частично и окончательно реализовать его в наследнике.

<определение-реализации-интерфейса>

            РЕАЛИЗУЕТ [ИНТЕРФЕЙС] <имя>

            Означает начало секции реализации интерфейса классом. Продолжается до определения  КонецИнтерфейса. Внутри этой секции описываются привязки абстрактных элементов интерфейса к конкретным методам реализующим их функциональность. Например,  если в интерфейсе было определение Функция Фуу() Абстрактная, то в секции реализации должно быть определение Функция Фуу() <атрибут-замещения> := <привязка-реализации>. Реализация интерфейса должна находиться в публичной секции. Реализация интерфейсов внутренне или защищенно не предусмотрено (версия-0). Элементы интерфейса не доступны через контекст самого класса. Для доступа к ним необходимо вызвать метод .ДайИнтерфейс(<имя>), который возвращает контекст со свойствами и методами описанными в определении интерфейса. Или неопределенно, если класс не реализует запрошенный интерфейс. Если реализуемый интерфейс в свою очередь унаследован от других интерфейсов, то его реализация его свойств и методов автоматически приводит к неявной реализации соответствующих свойств и методов его базовых интерфейсов. Допустимо создавать несколько секций реализации интерфейса.

Версия-0: если у класса уже есть реализация одного из базовых интерфейсов реализуемого интерфейса (непосредственно или унаследовано), то генерируется ошибка; также, попытка реализации базового интерфейса, а не наследника приводит к ошибке.

<определение-переменная>

ПЕРЕМ <имя> [,] [<атрибуты-переменной>]

            Объявление переменной. Допустимо только при определении класса и только вне блока реализации интерфейса.

<атрибуты-переменной> ::= [СТАТИК] [ТолькоЧТЕНИЕ | ТолькоЗАПИСЬ][<область-видимости>]

Если не указаны атрибуты <только-чтение-запись>, то переменная доступна и для чтелия и для записи.

<определение-свойство>

При определении интерфейса:

СВОЙСТВО <имя> [,] АБСТРАКТНОЕ [<только-чтение-запись>][<область>]

где

<только-чтение-запись>::=      ТОЛЬКОЧТЕНИЕ | ТОЛЬКОЗАПИСЬ

При определении класса:

СВОЙСТВО <имя> [,] [<модификатор>] [<область>] [<привязка-свойства>]

СВОЙСТВО <имя> [,] АБСТРАКТНОЕ [<только-чтение-запись>][<область>]

где

<привязка-свойства>::=          [ЧТЕНИЕ := <имя>] [ЗАПИСЬ := <имя>]

<определение-функция> и <определение-процедура>

ФУНКЦИЯ <имя> [,] [ПЕРЕГРУЗКА] [<модификатор>] [<область>] [<привязка>]             

ПРОЦЕДУРА <имя> [,] [ПЕРЕГРУЗКА] [<модификатор>] [<область>] [<привязка>]

где

<модификатор> ::=

АБСТРАКТН(АЯ|ОЕ)

|  СТАТИК

            |  (ЗАМЕЩАЕТ | ЗАМЕЩАЕМ(АЯ|ОЕ) | НЕЗАМЕЩАТЬ | ЗАМЕЩАТЬОБЯЗАТЕЛЬНО)

<привязка>::=

:= <имя>

<определение-конструктор>

КОНСТРУКТОР ([<список-аргументов>]) [ПЕРЕГРУЗКА] [<привязка>]

КОНСТРУКТОР ()

Привязка конструктора должна быть процедурой и указывать ее обязательно. Допустимо не указывать привязку для конструктора без аргументов и атрибута перегрузки при размещении его во ВНУТР/ЗАЩИЩЕН секции. В этом случае строка определения трактуется как переопределение области видимости конструктора по умолчанию. Таким способом определяется не создаваемый публично класс. Публично не создаваемые классы не добавляются к списку методов свойства компоненты .СоздатьКласс и не имеют статического метода .СоздатьКласс() в публичном контексте определителя класса. Метод .СоздатьКласс() присутствует только во внутреннем контексте определителя класса и, таким образом, доступен для статических свойств и методов класса. Унаследоваться от такого класса тоже нельзя.

            Перед вызовом конструктора все переменные экземпляра класса устанавливаются в неопределенно. Вызывается конструктор самого младшего наследника. Синтаксиса делегирования вызова конструктора в версии-0 нет. Поэтому конструкторы базовых классов компонентой не вызываются! При необходимости вызова явно объявленного конструктора базового необходимо вызывать его вручную в процедуре конструктора класса в виде ЭтотКласс.МойБазовый.Конструктор([<параметры-конструирования-базового>]);. Вызван ли реально конструктор базового класса компонента не контролирует. На момент вызова конструктора класс уже полностью сконструирован и все замещаемые элементы замещены. В любом случае старайтесь избегать вызова виртуальных методов из конструктора и деструктора. При возникновении исключения в процедуре конструктора компонента перехватывает его, очищает переменные, удаляет выделенную память и пробрасывает исключение платформе. Что примечательно, платформа в этом случае его корректно перехватывает и краха не происходит. В отличие от деструктора – там платформа явно не готова к замысловатому сценарию после .Release(). Также, если вы успели сохранить ЭтотКласс в какой-либо переменной, после исключения в конструкторе крах неизбежен. Планирую перейти на передачу слабой ссылки на ЭтотКласс, как ужк сделано в деструкторе. В любом случае – старайтесь не допускать (не выпускать) исключений в конструкторе и деструкторе.

< определение деструктор>

            ДЕСТРУКТОР () <привязка>

            Привязка в определении деструктора обязательна.

Когда счетчик ссылок экземпляра класса достигает нуля компонента вызывает определенные для класса процедуры деструкторов начиная с наследников и к базовым. После этого компонента дополнительно принудительно очищает все переменные класса и освобождает память. В качестве значения ЭтотКласс процедуре деструктору передается специальный объект СсылкаНаКласс через который можно точно также получать доступ ко всем элементам класса. По выходу из тела процедуры деструктора ссылка, даже будучи сохраненной в какой-либо переменной, очищается и превращается в ПустуюСсылку. Попытка вызвать какие-либо элементы класса через пустую ссылку приводят к ошибке. ПустуюСсылку можно только сравнивать с объектом возвращаемым свойством компоненты .ПустаяСсылка. Класс удаляется вне зависимости от сохраненных где-либо ссылок на него.

Версия-0: Процедура деструктор не должна выбрасывать исключения!!! Приводит к краху на втором вызове деструктора!!!

<определение-секции-области-видимости>

ЭКСПОРТ:

ЗАЩИЩЕН:

ВНУТР:

            Действие распространяется на все элементы класса до определения следующей секции или до конца класса. В начале класса по умолчанию устанавливается в ЭКСПОРТ.

<комментарии>

            //<любой-текст-до-конца-строки>

Задумано, но не реализовано

- Наитивная поддержка коллекций 1С. Для языка обрабатывающего данные это очень важно.

- Первичная инициализация статических членов.

- Комментарии в строке.

- Переопределение области видимости элементов.

- привязка свойства на свойство

- Множественное наследование. Важно для реализации аццессоров коллекций.

- Языковая конструкция ИСПОЛЬЗОВАТЬ.

- Операторы. Есть основания полагать, что интерфейсы 1С позволяют реализовать концепцию операторов «сравнение» и операторов преобразования_к_ «БУЛЕВО», «СТРОКА», «ДАТА», «ЧИСЛО».

- Делегирование вызова конструктора базового класса.

- расширенные атрибуты.

- декларирование функций ос и сторонних dll.

- расширение алгоритма определение перегрузки методов до интерфейсов объектов.

- Свободные свойства\методы, или свойства\методы расширения. На данный момент все привязки обязаны соответствовать определенной сигнатуре. Возможно к контекстам класса подключать свойства\методы без требования на первый аргумент. Возможно это новая языковая конструкции МОДУЛЬ.

- Типизация. Расширять применение вплоть до дженериков и до проверки типов данных методов привязки.

- Методы по умолчанию. Если метод с именем <имя> в контексте отсутствует, но есть свойство с именем <имя> и это объектное свойство с методом по умолчанию то вызываем этот метод. Естественными кандидатами на такие объектные свойства являются делегаты, объекты ТИП, и объекты имеющие метод с атрибутом МетодПоУмолчанию. До концепции typedef. Обратная ситуация – использование имени метода как свойства – естественная конструкция для возврата делегата метода. Не разрешать и разрешать только если явно указано определение соответствующего свойства.

- обвязка тестами

- демонстрационная реализация паттернов

- <вы можете дополнить (а лучше уменьшить) этот список>

Статус разработки.

Компонента реализует расширение языка, а язык должен быть бесплатным. Поэтому:

Использование представленной в статье компоненты в познавательных, образовательных и коммерческих целях бесплатно. Автор не исключает возможных коммерческих расширений технологии как самим автором, так и сторонними разработчиками при соблюдении условий бесплатности самого языка и ненанесении вреда коммерческим интересам компании 1С и ее деловой репутации. В случае использования в коммерческих приложениях автор готов заключить «договор с законным обладателем копии программы 1С по доработке ее в соответствии с ее функциональностью и без вмешательства в исходный код программы». В этом случае, при необходимости обеспечения юридических формальностей, автор оставляет за собой право устанавливать стоимость договора в пределах издержек автора на обеспечение юридической схемы.

В рамках своих возможностей, по мере накопления улучшений, исправлений и доработок я буду выкладывать их в публичном доступе.

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

Почта:             v8classes@gmail.com

WMU:             U110651501027

WMR:              R444928807260

WMZ:              Z529168937078

Спасибо.

См. также

Медиадисплей. Рекламный информационный монитор для покупателя.

Разработка внешних компонент POS терминал Рабочее место Розничная торговля Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Рестораны, кафе и фаст-фуд Реклама, PR и маркетинг Управленческий учет Платные (руб)

Монитор покупателя может отображать текущую покупку на кассовом месте, показывать видеорекламу, баннеры, во время простоя разворачивать рекламу на весь экран. Можно использовать в качестве графического меню-борда в кафе и видеовывески. Управление выводом на телевизор через hdmi-приставку на базе Windows или Android. В качестве устройства отображения можно использовать Android-планшеты, фоторамки с Android, монитор любого Windows-компьютера, доступного по сети. Настраивается ЛЮБОЙ ДИЗАЙН экрана!

16800 руб.

30.05.2017    52055    34    69    

43

Внешняя компонента для сканирования (замена TWAIN-компоненты БСП) (Native Win 32/64)

Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента позволяет работать c TWAIN-совместимым оборудованием (сканерами, камерами) . Полностью совместима со стандартной TWAIN-компонентой из БСП и может применяться как ее замена без изменения вызовов, при этом может работать с 64-разрядной платформой, а так же имеет расширенную функциональность, например, сохранение результата непосредственно в PDF без использования сторонних утилит. Прекрасно работает на сервере, тонком клиенте и веб-клиенте (проверена работа в браузерах Google Chrome, Mozilla Firefox и Microsoft Internet Explorer).

2400 руб.

12.05.2020    26161    131    99    

82

Внешняя компонента печати PDF (Native Win 32/64)

Разработка внешних компонент Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Внешняя компонента позволяет печатать PDF файлы непосредственно из 1С, не используя при этом сторонних программ. Прекрасно работает на сервере, тонком клиенте и веб-клиенте. Основана на проекте PDFium из состава проекта Chromium/Chrome

1500 руб.

17.09.2018    35018    104    123    

111

Мастер создания внешних компонент 1С (технология COM) для DELPHI 6/7/8/2005/2006/2007/2008/2010/XE/XE2/XE3

Разработка внешних компонент Платформа 1С v8.3 Платные (руб)

Средство для сверхбыстрой разработки внешних компонент 1С:Предприятия 7.7 и 8 по технологии COM на всех версиях DELPHI, начиная с 6.

2000 руб.

28.03.2013    53969    35    14    

68

Внешняя компонента для подключения 1С к телефонии Asterisk

Разработка внешних компонент Телефония, SIP Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Внешняя компонента выполнена по технологии Native API для 1С 8.х, обеспечивает доступ к программным АТС Asterisk (FreePBX, Elastix) через AMI интерфейс. Через него можно управлять многими функциями Asterisk (определение номеров, перевод звонков, набор телефона и т. д.)

2400 руб.

04.05.2018    44900    116    64    

60

QR-код с логотипом компании (обычная и управляемая форма)

Разработка внешних компонент Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Как известно, стремление сделать свою рекламную продукцию запоминающейся и выделяющейся — верный путь к успеху. Сегодня, мы поговорим с вами о том, что можно сделать с обычным черно-белым QR-кодом, чтобы он стал более живым и привлекательным. Если вам не терпится попробовать сделать QR-код с логотипом компании, то эта обработка для вас!

2400 руб.

22.06.2016    30822    4    4    

8

Внешняя компонента GraphQL клиент для 1С

Разработка внешних компонент Платформа 1С v8.3 Платформа 1C v8.2 Платные (руб)

Внешняя компонента, позволяющая посылать команды и получать ответы по GraphQL протоколу из 1С.Может быть использована при интеграции. В 1С работает на стороне "клиента".

4600 руб.

27.06.2023    2650    1    0    

2

Компонента ExchangeStruc (Структура Обмена). Прямой обмен данными между потоками, сессиями и окнами.

Разработка внешних компонент Платформа 1С v7.7 Платформа 1С v8.3 Платформа 1C v8.2 Платформа 1С v8.1 Россия Платные (руб)

Аддон "Структура Обмена" (ExchangeStruc) - это компонента, которая обеспечивает доступ к разделяемым процессом структурам, аналогичным структурам 1С. Обеспечивает прозрачную передачу данных примитивных типов, в том числе Двоичных данных, в режиме Реального времени между разными контекстами (формами) или потоками одного процесса. В перспективе функционал будет расширен для обмена между процессами, даже разных версий платформ. Совместим с версиями Windows рабочих станций и серверов, с платформами 1С разных версий и релизов в режиме Native начиная с 8.2, и в режиме COM начиная с версий 7.7. По скорости чтения и записи лишь немногим уступает стандартной структуре 1С. НОВОЕ: Добавлен функционал регистрации компоненты COM в качестве OLE Auto (COMОбъект) для поддержки её работы в серверах старых версий 1С: 8.0 и 8.1, где работа с компонентами исключена. Теперь можно коммуникацию с Фоновыми заданиями на этих версиях проводить.

7200 руб.

19.04.2023    4784    1    0    

3
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Aphanas 92 28.10.16 11:21 Сейчас в теме
Когда-то пытался реализовать подобие ООП на Windows Script Component (WSC), язык использовался JScript. Определения классов задавал похожим образом, только использовался синтаксис WSC (т. е. XML, по сути).
Бросил, когда понял, что если делать ООП, то это нужно делать с возможностью наследовать штатные объекты 1С. Да еще желательно так, чтобы получившиеся потомки могли быть использованы вместо штатных объектов (т. е. в качестве параметров стандартных функций и т. п.). Кроме того, при использовании COM, нужно забыть про кроссплатформенность, а также про веб-клиент, что весьма печально.
Однако, это лишь мой личный выбор, Бывают задачи, когда ООП реально не хватает. Согласен насчет мышления в стиле ООП. Каскадные вызовы общих модулей в типовых конфигурациях - ничто иное как суррогатная замена некоторых механизмов ООП.
Успехов, видно проделана большая работа.
dj_serega; JohnyDeath; ybatiaev; CyberCerber; Lem0n; +5 Ответить
3. IntelInside 128 28.10.16 13:51 Сейчас в теме
(1) Aphanas, Спасибо. Успех, удача и все что их сопровождает мне бы очень не помешали.
Относительно поддержки штатных объектов 1С - это пункт <задумано-но-не-сделано>::<поддержка-наитивных-...>. Технически это не составляет большого труда в отношении основных объектов (Массив, Структора, Запрос, т.д.). Все (практически все за редким исключением) объекты 1С поддерживают COM-аггрегирование. Это будущая конструкция Класс МойМассив НАСЛЕДУЕТ 1С.Массив. Здесь нужно понимать, что 1С.Массив это объект реализующий не один интерфейс. Как минимум на первых порах поддержки сериализации не будет (см.ниже). Другая возможная конструкция Класс МойМассив НАСЛЕДУЕТ ИНТЕРФЕЙС 1С.Массив. Реализацию такой конструкции можно начинать делать хоть сейчас и все встроенные методы 1С, которым нужен только интерфейс массива не отличат это от родного массива. Не сделал это в версии-0 только потому, что это увеличит связность с платформой. На данном этапе мне хотелось бы "расшириться" на разные версии платформы, разные ОС и т.д. Вычухать баги. Обрасти юнит-тестами и только потом "углубляться".
ПС: код 1С уже не отличает где класс компоненты имитируюший к примеру Структуру, а где Структура 1С. В демке это есть. Моя технология родная для 1С. Ну почти-почти родная..
Относительно кроссплатформенности я не до конца понял.
Если имеется ввиду .so для линукса и т.д., то плюсы работают везде где есть процессор. Можно хоть сейчас начинать готовить выпуск для STM32 и через n времени оно откомпилируется. Линукс это моя первоочередная задача. С Андроидом посложнее (и это вызов!), но тоже возможно. Но это будет версия-зависимый эксклюзив.
Если имеется ввиду поддержка клиент-серверных возможностей 1С, то это а) поддержка наитивных интерфейсов сериализации. б) регистрация некоторых объектов во внутреннем реестре 1С и, естесственно, загрузка компоненты на всех машинах. Все решаемо. Это я планирую для версии-1. Пока просто рано тратить время. Пока на боевой сервер мою компоненту не будут грузить не потому что она что-то не поддерживает. Надо достичь стабильности и доверия.
Спасибо.
4. Steelvan 302 28.10.16 14:27 Сейчас в теме
(3)

Жесть, насколько тяжело читается текст последнего вашего сообщения.
Попробуйте меньше использовать "не" и текст сразу станет чище и понятнее.
http://foolks.org/samorazvitie/psixologiya-vliyaniya-negativnye-chasticy-ne-ne-ispolzovat-chasticu-ne/
2. bulpi 215 28.10.16 13:18 Сейчас в теме
Плюс поставил. Автор, конечно , гигант, но...
1)Хотел бы я иметь столько времени для всякой фигни :)
2)Все эти "игры разума" никак не помогут для внедрения 1с в жизнь реального предприятия. Впрочем, сильно и не помешают.
InExSu; BigB; +2 Ответить
5. vasvl123 118 28.10.16 15:59 Сейчас в теме
А отдельно от платформы работает? Например из 1script?
6. ture 606 28.10.16 16:45 Сейчас в теме
(0) Зачем?

Код ООП красив в первую очередь наглядностью и уже потом своей парадигмой конструирования решения. Цена тоже известна - огромное количество переходов (вызовов функций и возвратов из них). Ваша реализация обещает только второе, но кому? Тем, кто не силен в процедурном программирование или у него ООП головного мозга? Аналогичное решение на 1С77 было изящней, но программисты 1С избегали и его всеми силами.
kuzyara; klimsrv; awk; Spacer; CyberCerber; +5 Ответить
7. IntelInside 128 28.10.16 21:21 Сейчас в теме
(6) ture,
OOP, or not OOP: that is the question!
... but baltik number nine my best suggestion!
dgolovanov; +1 Ответить
10. o.nikolaev 211 29.10.16 14:00 Сейчас в теме
(7) :-) IS my best suggestion
CyberCerber; +1 Ответить
21. ybatiaev 58 31.10.16 15:28 Сейчас в теме
(6) ture, напишу свой взгляд на проблему
ООП головного мозга

1С приближается к международному стандарту программирования, что уже радует.
И написать советы ЧТО надо бы сделать не приветствуются ни самими разработчиками 1С, ни сообществом обученных процедурному программированию.
Желания клиентов, не в расхождении с законом, всегда было в приоритете. Есть желание - должно быть простое решение. Точнее те, у кого "ООП головного мозга" видит решение в 3-5 строчек кода. Но в связи с процедурным программированием сделать ПРОСТО не получается. Рефакторинг хорошая штука, но в итоге код получается СОВСЕМ НЕ ЧИТАБЕЛЬНЫМ. Те, кто владеет ТОЛЬКО процедурным программированием ограничен и в решениях и в мышлении. И это навязывается при обучении как истинно верное решение. И потом все программеры с заложенным в них процедурным программированием думают, что все дураки (это моё мнение!!!).
Сколько сам писал предложений, всегда говорил, что вот вам идеи бесплатно, но, кроме минусов, ничего. Хотя спустя год-два к этому приходят. Вот написал предложения к расширениям. Минусов куча, но вот внедрили же условие КОГДА доп код запускаться ДО или ПОСЛЕ основного кода. Но изврат расширений так и остаётся. Да, будут "удобства", но если не в том направлении развивается, то зачем развивать именно неправильное направление?
25. ture 606 31.10.16 18:26 Сейчас в теме
(21) Скоро, товарищ, скоро мы увидим как 1С сделает свободные тейблы и предложит самим написать классы, для работы с ними. Смекаешь? (так во всех ерп делают сегодня, а велосипед 1С некогда изобретать).

Классы в 8.4? На подлете точно, или рынок так и не увидит ЕРП от 1С, стоящую на ногах.
pvlunegov; +1 Ответить
8. Solovyeff 29.10.16 01:38 Сейчас в теме
9. o.nikolaev 211 29.10.16 13:56 Сейчас в теме
За работу ставлю плюс конечно, но... в реальных больших проектах это использовать? Вряд ли... Как задел на будущее? Ну не знаю. Без платформенной поддержки это, на мой взгляд, так останется любопытным концептом. Очередной "вариацией на тему", не более.

Далее идет вольное рассуждение, так сказать "на тему" и "пользуясь случаем"...

ООП 1С-ке не хватает-не хватает, это видно по тому же ЕРП 2, где средство (язык & инструментарий-конфигуратор) перестали справляться со сложностью продукта и по исходным кодам видно, как команда мучительно пытается что-то с этим сделать. Рецепта, кроме как повышения уровня абстракции, а в данном случае это ООП, нет. Но позвольте, ЕРП 2 только-только задышала, а тут что, опять переписывать? Да никто не пойдет на это, и я прекрасно понимаю почему. Потому что это адЪ. Но пытаются, пытаются конечно хоть что-то сделать. Вон и определяемые типы данных ввели. Видимо задел под ОО? Ну, пожмем-увидим, как говорится.

Я уже не говорю о поддержке многопоточности и асинхронности на уровне языка сразу, которые ой как нужны (да они есть, но с танцами и бубном). Но, как говорится, если вы такие умные, где ваши деньги? Не нравится 1С-ка - велкам, полно других языков, платформ и прочего. Дерзайте (это я уже себе говорю)!

Сейчас народ изгаляется кто как может и кто во что горазд. В кодах одной фирмы, которая занимается ЭДО (не скажу какой) формы обработки сделали "типа классы" и в таком микс-стиле написали все. Работает? А то. Но поддерживать и дорабатывать это? 8-(

В общем, согласно тезиса Великого Кормчего, "расцветают все цветы" и "соревнуются тысячи школ мысли" в бесконечной и неравной борьбе аристотелевой бинарной логики со сложностью квантового реального мира. Но, увы, "серебряной пули" пока нет как нет.
Merkalov; sandybaev; dj_serega; BigB; brr; CSiER; +6 Ответить
11. CyberCerber 851 29.10.16 14:41 Сейчас в теме
Насколько я люблю, и насколько мне не хватает ООП в 1С, но ваша разработка меня не воодушевила.
Как уже говорили выше, ООП должно давать легкое понимание и читаемость кода, а здесь этим и не пахнет.
А вообще, мне, например, ООП в 1С нужно, чтобы не создавать какие-то свои классы "Здрасьте", а наследовать существующие объекты платформы, и тем более объекты конфигурации.
Вот как порой не хватает возможности взять и наследовать исходный документ или обработку... Например, есть КассовыйОрдер, а от него Наследуются ПКО и РКО. Сейчас приходится просто заниматься копированием. 1С сделала хоть небольшой шажочек в эту сторону - Расширения, но хочется полноценного наследования.
Плюс поставил, так как очень уважаю таких энтузиастов, которые хотят сделать продукт лучше, но, боюсь, настоящего решения можно ждать только от 1С.
InExSu; dj_serega; JohnyDeath; amoarok; SunShinne; HAMMER_59; Spacer; CSiER; +8 Ответить
12. CSiER 35 29.10.16 18:15 Сейчас в теме
За идею и реализацию однозначно плюс! Проект интересен. Планы серьезные (чистое множественное наследование это плохо и не нужно, но это имхо конечно ☺). За всем этим пока не вижу глобальной идеи - положим, появилась на свет стабильная версия (с дженериками, интернал/экстернал интерфейсами, лямбдами, тонной синтаксического сахара и другими прелестями) - какой профит это даст рядовому разработчику (возможность дополнить типовую коллекцию своим итератором и т.д. это хорошо, но хочется большего)? Хорошо, предположим, что образовалось коммьюнити, которое активно будет переносить базовые алгоритмы и структуры данных «от больших братьев» (от хешмэпов из Java, до leftpad из ноды ☺), но ведь вендор этого не поддерживает. Каким Вы видите проект в будущем (как он будет развиваться в прикладном смысле для рядовых 1сников)?
CyberCerber; +1 Ответить
13. artbear 1447 29.10.16 19:14 Сейчас в теме
Автору респект. Но название 1С++ давно захвачено :( с 2001 года продукт существует
22. IntelInside 128 31.10.16 17:24 Сейчас в теме
(13) artbear, Спасибо за замечание. Само вырвалось. Вообще-то я это учитывал и в коде и в документации использовал везде 1С+классы. С картинкой вообще дурацкая история - редактор Инфостарт не хочет принимать статью без логотипа. Когда я скармливал ему первую статью, то уперся в это в последний момент и пришлось буквально на ходу фотошопить. А к второй статье подзабыл и пришлось старую вставлять. В названии статьи как-то само вырвалось. Отредактирую и текст пересмотрю. Картинку как доберусь до фотошопа переделаю на один плюс. Итак - проект называется 1С+классы. Картинка 1С+. Если, бог даст, будут у меня еще проекты то они будут идти под этой картинкой и именоваться 1С+<вербальное-имя-проекта>. Еще раз прошу прощения. Надеюсь на этом инцидент будет исчерпан.
Спасибо.
14. DenisCh 29.10.16 19:58 Сейчас в теме
Почитал. Ещё раз убедился, что в проблемно-ориентированном программировании (каким является 1с) - ООП нужен до уровня ширинки.
Сурикат; +1 Ответить
15. tradeagent 30.10.16 21:57 Сейчас в теме
Автор, прошу простить меня за сказанное далее. Но получившийся у вас код выглядит ужасно не читабельно по отношению к привычному типовому коду 1С. Я бы от поддержки такого кода всеми силами бы старался отказаться. Ничего плохого про самое решение сказать не могу.
CyberCerber; +1 Ответить
16. eugeniezheludkov 43 31.10.16 06:48 Сейчас в теме
ОФФТОП: Всегда ненавидел эти Си++ заголовочные файлы где сначала обьявляют, что будет (нет не интерфейс, а именно тупо обьявление что будет реализовано), а потом в ЦПП файле реализация. Если хочешь добавить новый метод, приходится добавлять его дважды, неудобно и нечитабильно ИМХО. Когда пишу что-то свое с нуля то пишу этот класс в одном .h файле и не парюсь.
38. IntelInside 128 02.11.16 18:36 Сейчас в теме
(16) eugeniezheludkov,
:) Вся компонента так написана. Пока. Но придет черед сурового gcc и придется рефакторить. Но это даже хорошо. Чем больше рефакторишь, тем меньше кода. А чем меньше кода, тем меньше глюков.
39. eugeniezheludkov 43 07.11.16 10:18 Сейчас в теме
(38) так я как -раз в суровом gcc и компилю где у меня .h файл сразу же содержит реализацию класса без объявления этого не наследуемого "недоинтерфеса"
17. Evil Beaver 8100 31.10.16 10:44 Сейчас в теме
автор просит, всех кто находит предложенную технологию интересной и полезной, о пожертвовании на ее разработку и совершенствование


Я бы с удовольствием, но как мне понять - полезная ли это технология? Пока я читал статью, у меня взорвался мозг. И это при том, что я знаю, что означает "sizeof(uintptr_t)" и "virtual call".
Можете пояснить в двух словах, как мне (абстрактному "мне") это пригодится в жизни? ООП в 1С само по себе сомнительная штука, но даже если оно и нужно, то код из примеров вызывает у меня кровь из глаз.

Если совсем-совсем серьезно, то нам были бы полезны конкретные прикладные примеры, а не классические объяснения ООП на пальцах. В вузах, дай бог, все ООП учили и представляют себе. А вот представить себе, ради каких преимуществ нужно потратить время, изучив предлагаемую семантику классов (это ведь новый диалект, как ни крути, лишняя нагрузка на мозг) я как-то сходу не могу.

А так - очень круто, я помню еще первую вашу статью по внедрению в 1С:Платформу. Теперь бы эту энергию да в мирных целях куда-нибудь применить ))
JohnyDeath; eugeniezheludkov; awk; CyberCerber; +4 Ответить
20. IntelInside 128 31.10.16 14:01 Сейчас в теме
(17) Evil Beaver,
За пример к статье мне похоже нужно начинать извиняться. Это была попытка пошутить и, по видимому, неудачная. Вдохновением мне послужила шутка <Hello World Enterprise Edition> на java. То есть это не просто ООП, а его наихудшее enterprise проявление. Я только попытался придать хоть какой-то практический смысл этому нагромождению классов. Также хотел продемонстрировать использование паттернов, но код начал катострофически разрастаться - не для статьи. В дальнейшем примеры буду перефразировать отсюда <Паттерны проектирования в ABAP примерах>. Но это уже цикл из 20-30 статей. Ко всему прочему это действительно первая программа для этого языка. До этого были только отдельные тестовые пописульки на колене. Естественно вылезло с десяток ошибок и недоработок, которые приходилось на ходу править. Потом IDE 1С все это не поддерживает. Определения классов и реализацию можно было-бы разнести хоть в разные модули, но в статье все равно их показывать вместе.. Затем редактор Инфостарта все поковеркал перенося длинные строки. В общем АДъ. Поэтому даже название модуля я сделал двусмысленно сокращенным - ОопХелл. На тот момент мне все это казалось забавным. Но более никому это так не показалось и, похоже скоро меня начнут бить подозревая что я над всеми издеваюсь. Поэтому еще раз, официально, приношу извинения за неудачный пример к статье. Постараюсь исправиться.
Теперь почему я все время говорю о языке. Дело в том, что это третья версия. Первая моя попытка была формировать типа классы через некоторое API (продолжение техники из перфой статьи). Вторая - некие самобытные самоконструирующиеся объекты-классы. Типа присвоил значение свойству - и свойство появилось, присвоил делегат - и метод появился. Все это я торжественно отнес на помойку. Это несистемные решения. Такое может пригодиться разве что мне и еще паре гиков. Но уж точно не заказчику\работодателю. Это в высшей степени причудливый велосипед от велосипедиста неотделимый. Поэтому я засел за реализацию ООП с нуля пользуясь только стандартом С++ и своими соображениями относительно синтаксиса и призвания Бейсика, ну и конечно поглядывая на java, vb.net, etc. То что у меня получилось, как мне кажется, это полноценная реализация ООП для COM. Т.е. это то чем должен был бы быть VB7, если бы MS его не угробил. Из этого вытекают следующие следствия.
Перенос кода из/в 1С+, MorphX and X++, ABAP, JAVA, т.д. не требует смены парадигмы и может быть выполнен в (полу)автоматическом режиме плюс напильник. Фактически большая часть проблем будет с библиотекой времени исполнения, но у 1С она уже достаточно развита, а недостающие части можно и дописать. Для .net платформы такие трансляторы c# <-> vb <-> java существуют и выдают неплохие заготовки. Далее. Я не писал вычислительное ядро (ну то что 2+2 считает). Т.е. представленную реализацию можно назвать 1С+классы для виртуальной машины 1С. Но вычислительное ядро может быть любым умеющим делать с++ virtual call. Реализацию потенциально можно выполнять хоть на java, хоть в машинные коды откомпилировать - ironEs.
Следующее следствие. Поскольку компонента реализует полноценный "взрослый" ООП для COM-интерфейсов, то разработчики 1С практически лишены возможности сделать что-то иное. Кратчайшее расстояние между двумя точками есть прямая. Ну разве что в зазеркалье иная метрика пространства и "значение синуса может достигать 4". Т.е. если ООП появится в платформе, то решения возможно будет оттранслировать 1С+ <-> 1Сv9.
Практика наработанная с 1С+ также применима в других языках, программах, организациях, государствах. Т.е. "среднестатистический одинэсник" может стать senior odines developer -ом. С соответствующим ростом ЗП.
Возможна наработка практики и кодовой базы под серверные расширения 1С 8.4.*
Об 1script. Если нас скрестить, то получится вполне себе полноценный и современный новый язык программирования высокого уровня. Тот самый "национальный Бейсик" о котором я упоминал в статье. Как мне кажется это направление имеет самостоятельную ценность. Правда только для .net платформы т.к. 1script написан на и для net.
Вообще мы сейчас имеем странную и парадоксальную ситуацию. У меня есть классы, у 1script виртуальная машина, у Снегопата IDE, у 1С++ 7.7 наработки по ООП. Все это вкупе решает основную проблему 1С - язык. Но сама 1С этого не хочет. Революционная, короче, ситуация. Прямо в смысле марксизма-ленинизма.
Об ООП я чуть позже напишу. Очень вкратце - я не поборник ООП - уменя очень негативный опыт его бездумного использования, но поддержка его есть во всех современных языках программирования. Потом - почему все считают что в 1С нет ООП. Уверяю вас под капотом платформы его столько, что голова кругом идет. Только на данный момент программист его использовать может только валяясь на коленях перед отделом разработки 1С. Можно еще попробовать взятки давать, чтобы они нужный до зарезу класс сделали. Моя же компонента дает возможность сделать класс самому. Набить свою шишку, переделать, сделать лучше. Как я уже говорил взаимодействие с объектами платформы это всего лишь вопрос времени. А для меня (вернее в первую очередь для моей жены) это вопрос денег. Я бы этим только из чувства прекрасного занимался, но нужно быть серьезным - большие дела в одиночку, урывками, вместо сна не делаются. Некоторых своих сугубо личных целей я уже достиг - если нужно высокопроизводительную числодробилку подключить - умею, нужно замысловатую иерархию классов - пожалуйста. Т.е. работать с 1С как с бейсиком я научился. А мечт вообще громадье. Хотя я и подустал, но до некоторой логической точки "версия-1" проект доведу. Вероятно нужно кроме теоретической части сделать еще некоторую практическую опцию.
Спасибо.
PS. Я на все вопросы постараюсь отвечать, возможно только не сразу. Возможно нужно FAQ делать. И еще раз прошу прощения за неудачный пример.
PPS. ООП кстати не все в институте учили и не все вообще в институте учились. Поэтому некоторую нудность прошу потерпеть.
PPPS. Похоже опять в двух словах не получилось..
zhenyat; dgolovanov; CyberCerber; +3 Ответить
52. gbiperm 16.03.17 11:22 Сейчас в теме
(20)
Уважаемый, возмите с++ за пример:
Например я хочу:
1. Модификаторы доступа: private, pablic, protect, static
2. Множественное наследование (Представлю как мозги вскипят, когда я в свой класс унаследую от Справочника, Документа, Плана счетов, и Регистра) :)))
3. Хочу перегрузку операторов :))) методов... и стандартных функций платформы...
4. Указатели...
5. unsafe конструкции
6. Динамическу работу с памятью :)

7. Хочу при выстреле в ногу, отстрелить ноги всей команде...

Это шутка... не огорчайтесь...

Но ООП 1С скорее не будет реализовывать...тогда все от нее просто разбегутся...
ООП мне не хватало в 1с77 при интеграции со внешними системами... в 1с8 это поправили...

А что касаемо Java EE 7.
Java Platform, Enterprise Edition, сокращенно Java EE (до версии 5.0 — Java 2 Enterprise Edition или J2EE) — набор спецификаций и соответствующей документации для языка Java, описывающей архитектуру серверной платформы для задач средних и крупных предприятий.

Спецификации детализированы настолько, чтобы обеспечить переносимость программ с одной реализации платформы на другую. Основная цель спецификаций — обеспечить масштабируемость приложений и целостность данных во время работы системы. JEE во многом ориентирована на использование её через веб, как в интернете, так и в локальных сетях. Вся спецификация создаётся и утверждается через JCP (Java Community Process) в рамках инициативы Sun Microsystems Inc.

Каждая спецификация - одна компонента реализующая какую-то логику.
JSF например веб интерфейс на ней хорошо делают.
GlassFish - сервер приложений.
Hibernate - ORM
Spring, JavaFX -- клиенты любых покроев и пошибов...
Только JAVA EE7 это бум считать, если грубо, платформа общего назначения для построения любых приложений.

При этом в 1С8.* стараются такого же подхода придерживаться на текущий момент.
Тот же строго определенный набор доступных компонент(Объектов, уговорили :)) для решения учетных задач, ну еще и аналитики, хотя OLAP я бы уже на платформе 1С не рискнул бы делать, хотя можно извратиться... Т.е. Не все на 1С можно построить :)))
Сервер приложений то же есть...
ORM - присутствует...

А теперь под занавес С++ и простреленная нога:

class Class {
public:
~Class()
{
printf( "Class::~Class()" );
}
};

int main()
{
delete new Class[1];
return 0;
}

еще толком не написал, а уже программа не определенно завершилась.
Простите, но в 1С не глупы, и такое то же предвидят - чем сложнее язык,
И чем больше нюансов тем труднее спецов готовить...

Я согласен с EvilBear что в 1С 8.* сомнительное удовольствие...

Вам напомнить что произойдет с потомками в иерархии классов, если поменять базовый?
Да же в классическом программировании ООП имелось ввиду, множественное наследование сомнительно.

З.Ы. изучаю с++
53. Evil Beaver 8100 16.03.17 12:39 Сейчас в теме
(52) а если так?

delete[] new Class[1]; 
54. gbiperm 17.03.17 06:32 Сейчас в теме
(53) Все верно. Смысл был проиллюстрировать что начнет твориться, если взять так сказать Junior 1C программиста... И прилепить ООП полное в 9й версии 1С.

Если честно я не совсем чистый С++ изучаю, QT\C++ - можно считать одним из диалектов С++.
Там много потенциально не безопасных моментов убрано.
Если чего-то не хватает то там самые распространенные библиотеки STL и BOOST.

То, что в QT убрали много не безопасных моментов - это меня да же радует.
Но без базовых знаний С++ например указатели, работа с памятью и т.п. мало что пойму.
Так что тихо едем и читаем Страуструпа и решаем упражнения :)

А сточки зрения работы - Системное администрирование.
Иногда приходится на низком уровне писать - утилиты, или например как вариант модули в SQL сервера - MS SQL и PostgreSQL поддерживают такое расширение. Хотя на практике не доводилось.

Если с точки зрения Системы учета от 1С (Платформа + конфа) - то же подойдет QT(ток поставить нужно не забыть) и все что мне от ООП не хватало, тех объектов, то просто зашить их в компоненту на Ntive API. ИМХО.
55. dmpas 417 17.03.17 10:23 Сейчас в теме
(54) нафиг Си++ ! Golang изучайте!
56. gbiperm 17.03.17 12:08 Сейчас в теме
57. dmpas 417 17.03.17 13:10 Сейчас в теме
58. gbiperm 17.03.17 13:24 Сейчас в теме
(57) Хотя бы компоненты писать на Native API остальное за пределами данного ресурса.
Теперь ваш ответ.
59. dmpas 417 17.03.17 20:50 Сейчас в теме
(58) мой ответ целиком за пределами данного ресурса. если отвлечься от внешних компонент, на го пишется быстрее и очевиднее.
61. gbiperm 21.03.17 16:32 Сейчас в теме
(59) Я себе то же немного жизнь упростил. Взял библиотеку QT да многие небезопасные моменты исключены. Да стандарт то же решил взять посвежее С++11 или С++14.

А чтоб писать быстрее и очевиднее - мне питон нравится. Поглядываю в версию 3.*
И таки да в базовой конфе Unix/Linux идет g++ (отнюдь не gcc-go) и питон.
И так с какими ЯП я чаще буду сталкиваться? Ответ увы очевиден.

Еще чтоб писать проще быстрее и очевиднее есть PHP7 в котором подкрутили
Быстродействие...

И да это мое ИМХО.

А так я не проти Go но увы... задач под него нет...
62. dmpas 417 21.03.17 16:48 Сейчас в теме
(61)
И таки да в базовой конфе Unix/Linux идет g++

ээээээ... правда??? а я, дурень, руками его ставлю каждый раз. А "в базовой конфе Unix/Linux" вообще увело меня в размышления о вечном.


(61)
И так с какими ЯП я чаще буду сталкиваться? Ответ увы очевиден.

это bash, видимо.

(61)
Еще чтоб писать проще быстрее и очевиднее есть PHP7

слова "PHP" и "очевиднее" и в одном предложении у меня выдают ошибку компиляции, если честно.

Сойдёмся на том, что Qt - отличная штука :) (кстати, есть порт для Go)
65. gbiperm 22.03.17 06:49 Сейчас в теме
(62) sh :)

если на PHP писать как положенно с анотациями и т.п. -- т.е. соблюдать правила оформления кода, то вполне читаемо.
И вполне очевидно:) но да вы правы мало кто так делает :))))

Но примерно так же и фирма 1с требует оформлять код.

А про установку ручками - мне лень. чуть ниже отписался.
Ну да есть библиотечка скриптов(все что нужно чтоб получить требуемую мне базу), под те дистрибы которые использу.
Хостится в гите. Кочует со мной же. Выкачал, пересобрал. И раскатал. Притом пересборка просто пройдет рефлекторно наверное.
63. Evil Beaver 8100 22.03.17 01:02 Сейчас в теме
(61) базовый конфиг Unix/Linux это слакварь или, как минимум, гента. Там никакого g++ нет, не говоря про питон. А еще мне тут @nixel2007 показал вариант scratch. Так там даже echo нет. Вот это базовый так базовый.
64. gbiperm 22.03.17 06:39 Сейчас в теме
(63) я чаще использую CentOS то же поправил немного сам дистриб :) . Чисто для академического опыта собирал Gentoo ISO. и правил скрипт, для установки нужных пакетов автоматом. Почему чисто академический - так не используется у нас Gentoo. А когда нада один дистриб раскатать на много станций - тут уже ручками не поставить. Да и обновлять проще из локального дистриба. Дома клон убунты - Linux Mint. все что мне нужно робит. Т.к. дома я отдыхаю. Ну если есть у меня желание можно академические опыты с дистрибом поделать. И от одной убунты останется только ядро + php + mysql + apach+iptables - это к тому что из дистриба выпилить можно все что угодно и собрать как угодно.
18. fishca 1254 31.10.16 11:10 Сейчас в теме

Функция _Класс_Здрасьте_()
Возврат ""
"Класс Здрасьте"
"Защищен:"
" Конструктор()"
"экспорт:"
" Функция Идентично(другое_), Абстрактная"
" КонецКласса"
""
"Класс ЗдрасьтеТекст Наследует Здрасьте"
"внутр:"
" Перем м_текст"
"экспорт:"
" Конструктор(текст_) := ЗдрасьтеТекст_Конструктор"
" Функция Идентично(другое_), Замещает := ЗдрасьтеТекст_Идентично"
" Свойство Текст ЧТЕНИЕ := ЗдрасьтеТекст_Текст"
"КонецКласса"
""
"Класс ЗдрасьтеЖест Наследует Здрасьте"
"внутр:"
" Перем м_жест"
"экспорт:"
" Конструктор(жест_) := ЗдрасьтеЖест_Конструктор"
" Функция Идентично(другое_), Замещает := ЗдрасьтеЖест_Идентично"
" Свойство Жест ЧТЕНИЕ := ЗдрасьтеЖест_Жест"
"КонецКласса"
КонецФункции
Показать

просто жуть :(

Если так надо определять классы, то лучше не надо дальше что-либо делать.
Лучше взять идеи 1С++ и улучшить их, а не городить огород костылей и граблей(длинных и коротких).
pvlunegov; awk; Evil Beaver; +3 Ответить
26. IntelInside 128 31.10.16 19:02 Сейчас в теме
(18) fishca, (18) fishca,
Давайте для начала очистим от вынужденных деталей реализации:

Класс Здрасьте
Защищен:
Конструктор()
экспорт:
Функция Идентично(другое_), Абстрактная
КонецКласса
--
Класс ЗдрасьтеТекст Наследует Здрасьте
внутр:
Перем м_текст
экспорт:
Конструктор(текст_)
Функция Идентично(другое_), Замещает
Свойство Текст ЧТЕНИЕ
КонецКласса

То есть я убрал кавычки и детали привязки к реализации. В самом деле, зачем навязывать откуда взять текст определения класса. Программист и сам может загрузить его из файла, вычитать из таблиц БД или получить по почте в конце концов. Идеальным, конечно, является непосредственная запись в модуле 1С. Но это возможно сделать только в кооперации с проектом Снегопат. Или сама 1С это сделает. Я знаю как это делать и делал это для vb6 (он у меня BOOST и препроцессор использовал), но делать все в одиночку не имею возможности.
Относительно указаний привязки к реализации. Да. Загромождает. В последующих версиях, вероятно, придется допустить авто-подключение. Т.е. компонента сама в пространстве имен переданного объекта реализации будет искать методы с именами вида <имя-класса>_<имя-метода>. О формате еще надо подумать. Вынужденное и рискованное странными ошибками решение. Но да. Это :=бла-бла-бла загружают код катастрофически.
О самом определении класса в текстовом виде. Считаю это методологически верным решением. Функция чтения и письма осваивается детьми в самом раннем возрасте и нам наиболее естественно строить мыслеобразы именно читая текст. Война и мир в комиксах это профанация. Это, конечно, не исключает всевозможных визуальных построителей. Также не исключает некоторого reflection-api, которое внутри компоненты есть и тоже развивается. Но так или иначе определение сущности должно иметь текстовое представление.
Далее. За основу выбран синтаксис и дух Бейсика. Это один из старейших языков программирования и его особенностью является выраженная обучающая функция. В Си можно написать АСС ФУУ(БАЗ БАР) и компилятор Вас поймет. Опытному программисту лишние термины типа function, as и т.п. не мешают строить его и именного его мыслеобразы относительно данной и именно данной проблемы. Но это если в голове уже есть из чего строить эти мыслеобразы. В случае чистой и светлой головы мы должны раз за разом повторять Функция Фуу(Бар Типа Баз) Возвращает Асс. И что интересно. Мозг опытного программиста недостающую информацию автоматически восстанавливает, а по мере накопления опыта мозг начинающего излишнюю информацию начинает автоматически опускать. Результат один - мыслеобраз, составляющий минимальную единицу понимания программы. В случае Бейсика имеем выраженный минус - многословность. Но эту проблему должно решать IDE. Бейсик без толкового IDE это нонсенс. Но есть и бонус - если Вы разбираетесь в чужом коде, или в своем ннадцатилетней давности, или, простите, рисуете программку под шафэ, то возможность побуквенно прочитывать начинает помогать. Проверено.
Далее. Описания секций кода. Выделять их тоже является методологически правильным.
...
Впрочем если вкратце, то я готов объяснять если не понятно, отстаивать если уверен, признавать ошибочность своего мнения если докажут. И так далее. Я открыт для общения. Это версия-0. Оно только-только свое первое здрасьте сказало. Впрочем я готов и к тому, что кто-то останется только и только при своем мнении. Это грустно, но это жизнь. В любом случае спасибо.
19. ture 606 31.10.16 11:41 Сейчас в теме
(0) Я придумал, как тебе исправиться и очистить своё доброе имя на инфостаре.
Пишешь код на псевдо 1С (сам придумай разметку или возьми чистый шарп), код запихиваешь в текстовичек, а текстовичек отдаешь своей компоненте, которая вернет тебе экземпляр этого типа (объект класса). И вуаля!

Это будет медленней, чем писать на 1С раз в 100, т.к но это мерзкая гадость сделана намеренно самой 1С, чтоб не делали компоненты. Но! Какого рожна? Скорость в 1С? Не смешите меня. Это прокатит и будет круче поверь, чувак!
23. IntelInside 128 31.10.16 17:42 Сейчас в теме
(19) ture, Вообще-то компоненту можно попросить скушать чистый шарп простой заменой грамматических таблиц парсера. По ООП-возможностям языки равноценны или будут почти равноценны. Я по крайней мере к этому стремился и стремлюсь. Сахорку подсыпать только надо да "запрещено то что не разрешено" аккуратно поразрешать.
Сами же языковые возможности у 1С конечно несравненно беднее шарпа (я о виртуальной машине 1С, т.е. о реализации методов). Но имеется потенциальная возможность и компилировать шарпом, или gcc или <ваш-выбор>. Лишь бы удобный Вам язык реализации виртуальные функции вызывать умел (ну то-есть с COM интерфейсами умел работать).
И, простите, а что не так с моим именем?
24. ture 606 31.10.16 18:21 Сейчас в теме
(23) Что нет так? Для специалистов "++" означает с++, а это весьма хмурые ребята, которых тошнит от CLR и с#, ибо это надругательство со стороны m$ над с++. А ты написал совсем что-то недостойное "++". Для программистов 1С, код не читаемый и похож на кашу, что типовые конфигурации и рядом не стояли. Т.е. получается как писали выше "ООП головного мозга".

Короче, прячь публикацию, пока тебя не запомнили потенциальные работодатели. Подредактируй ее на что-нибудь нейтральное и выводи снова (звезды вроде не должен потерять).
27. IntelInside 128 31.10.16 19:21 Сейчас в теме
(24) ture,
По поводу ++ я уже ответил выше <artbear>. Это досадная ошибка. Нигде в самом коде и внутренней документации два плюса не используется. Название статьи и проекта будет отредактировано на "1С+классы".
По поводу каши почитайте ответ для <fishca>. В общем и целом в кашу код превращает импотентность 1С.
И знаете что... Спасибо! То что мои труд начинают сравнивать с типовыми конфигурациями уже лестно.

...и чего мы хмурые (смотрясь в зеркало), небритые вот только
28. kote 536 01.11.16 01:49 Сейчас в теме
ООП возник как более удобное средство разбиения системы на независимые части (удобно думать про неймспейсы) + идея хранить данные и методы их обрабатывающие рядом..

Ну не знаю.. может оно всё и работает - но пользоваться и поддерживать такой код - я не возьмусь.. страшно неудобно всё.
29. fishca 1254 02.11.16 08:48 Сейчас в теме
(0)
1. Для того чтобы сие творение хоть как-то отрывалось от земли, не говоря уже об взлете, я бы для начала пообщался на эту тему с зубрами 1С++
2. Пообщался на эту тему с зубрами опенконфа, снегопата && компани
3. И только после такого тесного сотрудничества и в теснейшем взаимодействии с ними разрабатывал хоть какой-то концепт технологии применительно к восьмерке.

Не надо отбрасывать опыт набития шишек, его необходимо использовать.

А так пока все эти слова про бейсик напоминают "запор мыслей, понос слов", вы уж извините за прямоту.
37. IntelInside 128 02.11.16 17:50 Сейчас в теме
(29) fishca, Спасибо. Я и пытаюсь с зубрами пообщаться. Только они, зубры, такие... к ним так просто не подойдешь. Без рабочего кода с одним "запором мыслей" вообще вариантов нет. Прошлая статья показала. Да и сейчас не гладко.
А за прорыв "запора мыслей" извините - накопилось. Материала много - я еще VB6 компилятору помогал, во free basic компиляторе копался, вот и с 1С не устоял. Судьба видно.
Нужно какое-то одно яркое практическое зерно. И народ потянется. Я вот только его никак ухватить не могу.
30. serg61 61 02.11.16 09:26 Сейчас в теме
Есть серьезные сомнения по поводу применения данных наработок:
1. Крупные компании всегда будут против любых поделок не поддерживаемых официально 1С.
2. По собственному опыту знаю, что ++ далеко не всем нужен. Вообще-то очень редко нужен, только когда проектируется новые объекты. Спасибо фирме 1С, что они взяли на себя эту работу.

Если автору некуда девать свободное время рекомендую написать транслятор с языка 1С (без всяких ++). Коммерческий успех гарантирован. Вижу следующие применения:
1. Использование для пакетной обработки команд, что-то тип .bat на языке 1С
2. Просто что-то надо посчитать студентам типа экономистам.
3. А если он будет встроен в какой-нибудь бесплатный ексел, то ему цены не будет.

33. orefkov 1152 02.11.16 09:53 Сейчас в теме
36. IntelInside 128 02.11.16 17:22 Сейчас в теме
(30) serg61,
Сторонняя реализация языка 1С - это OneScript. Очень путевый проект. У меня есть большие надежды на сотрудничество с ними. Если мою разработку добавить к их проекту то получится полноценный "национальный Бейсик" с весьма развитыми выразительными возможностями. Если развить еще тему типизации до уровня Nemerle и атрибутов, то на java можно будет посматривать свысока. Их в теме просто еще не было и я не знаю их планов. С моей же стороны требуется сформулировать интерфейсы взаимодействия дабы не публиковать интерфейсы 1С. Тем более они мне немного тесноваты - и вперед.

Я подумываю не о трансляторе, а о компиляторе языка 1С в машинный код. Что-то уже намечается...

А в OpenCalc есть UNO-бейсик, а вся технология UNO сама по себе интересна...

А для крупных компаний таки да - <не нужен>. Или по крайней мере пока <не нужен>. Только если <это> вырастет в полноценный проект и только если они оголодают на тощем рынке. Вот тогда да - в очередь выстроятся. Пока это только "тюнинг" для любителей. Впрочем аналогия с авторынком и рынком авто-тюнинга абсолютно полная. Это одинаковая и описанная в литературе бизнес-модель.

Ну и конечно ООП нужен для ЕРП++, но не перескочить через Предприятие++, но для этого надо Бух++, БСП++ ...
А в начале всего этого надо хоть пяток человек понимающих и 1С и ООП и необходимость такого пути.
31. st.gaevoy 26 02.11.16 09:40 Сейчас в теме
Однозначно плюс, т.к. любой прогресс начинается с энтузиазма одного человека, а далее подхватывается массой.
В любом случае ждем развития идеи. Будет развитие, возникнет и интерес со стороны 1С.
32. orefkov 1152 02.11.16 09:52 Сейчас в теме
Описания классов подгружать из файла, реализации распихивать по модулям обработок - это структурированнее будет и от Класс_Метод позволит избавится.
ЭтотКласс как параметр - ну, в питоне живут с self и ничего. Хотя конечно, можно и исхитрится и обойтись без этого.
Недостаток "ЭтотКласс" - при вызове нельзя выбрать, вызывать ли строго метод из базового класса или возможно переопредлённый в наследнике. Но тоже решаемо.

Только это уже было, реализация на подобном принципе - http://infostart.ru/public/19332/
Допилить то можно до боле-менее приемлемого состояния, но видимо, нет особой нужды в ООП в восьмёрке.
К тому же таки всё через COM - дополнительные задержки плюс линукс в пролёте. А нативные ВК - не поддерживают работу с объектами, только если с закатом солнца вручную, как в http://infostart.ru/public/541518/ - но это костыль ещё похлеще обсуждаемого.
Самое красивое, конечно же, было бы сделать реализацию на внутреннем движке 1С, по принципу снегопата, но релизо-зависимость... Хотя, в части работы с объектами 1С - она не такая сильная - с 8.2 ничего принципиально не менялось.
35. IntelInside 128 02.11.16 16:32 Сейчас в теме
(32) orefkov, Это вероятно какое-то или неточное прочтение или мое сумбурное описание.
Компонента полностью родная для 1С как и Снегопат. Я иногда использую термин 1С:COM, что подразумевает:
а) наследование от IUnknown
б) 1C:<типы данных> для параметров и возвращаемого значание
в) для возвращаемого значения не HRESULT, а любое допустимое в б)
г) ошибки в виде С++ исключения в 1С:<ошибка> формате (в т.ч. и через границу DLL)
Так построена и 1С и эта компонента, поэтому при компиляции под соответствующую платформу работать она будет везде, где работает и 1С. Сейчас выложена win32. Следущим шагом планирую lin32. Затем lin64. О win64 буду думать гхм... по политическим мотивам. Андроид и iOS не являются технически неразрешимой задачей, но там будет абсолютная версиозависимость. Поэтому это эксклюзив.

ЭтотКласс - калька с ЭтотОбъект, но не ЭтотОбъект во избежание конфликтов имен. Селф - по русски? Это не по-одинэсовски. Они где-то рассказывали, что у них целый отдел согласованиями имен занимается. Он такое не пропустил бы.

Вызвать метод базового класса - конструкция ЭтотКласс.МойБазовый.<имя-метода>
Свойство .МойБазовый возвращает именно контекст базового класса, без замещения виртуальных методов. Т.е. вызывается именно версия метода базового класса, а не наследника.
Возможность вызова ЭтотКласс.МойБазовый.МойБазовый.<имя-метода> подавляется принудительно. - разработчик базового явно должен дать такую возможность наследнику.

Подумываю только термин МойБазовый заменить на термин БазовыйКласс в окончательной версии. Т.е. чтобы было ЭтотКласс.БазовыйКласс.<имя-метода>

Если будет развитие проекта, то можно ввести специальную синтаксическую конструкцию для восстановления свойства БазовыйКласс в контексте базового у наследника для удобства разработчика.
Также (при развитии) в случае реализации множественного наследования видится ЭтотКласс.БазовыйКласс('имя-класса').<имя-метода> к примеру, хотя наверное есть и другие варианты.

Подгрузить же текст определения класса разработчик и сам может откуда ему заблагорассудится. Даже (поскольку это рантайм) он может вывалить пользователю окошко с текстовым (или иным визуальным) редактором, чтобы тот сам себе класс сделал.
Конечно можно и компоненте метод-сахарок сделать типа .ОпределитьКлассИзФайла(...), но у меня плохие предчувствия, что только пойди здесь на поводу, и только и будешь писать код загрузки определения класса из всех всевозможный источников во всех мыслимых форматах с обработкой всех возможных и невероятных ошибок... Ну в общем это до конца жизни.

Без нормального IDE и IntelliSense (короче Снегопата) жизнь будет очень скучна при любом методе загрузки.
34. dlebedev8 02.11.16 14:47 Сейчас в теме
Какой кошмар...
За старания плюс, конечно, но такое ООП в 1С точно не нужно. Вот если бы кто взялся и реализовал модель, основанную на сигналах а-ля Smalltalk, это был бы реальный взрыв мозга. А тут только запутывание похуже злосчастной БСП.
40. pro1c@inbox.ru 185 11.11.16 12:54 Сейчас в теме
ООП в 1С не нужен! И никогда не понадобится.
41. max1c 07.12.16 16:12 Сейчас в теме
Сделайте возможность передать одну функцию в другую как аргумент. И замыкания.
42. пользователь 07.12.16 16:31
Сообщение было скрыто модератором.
...
43. dmpas 417 07.12.16 16:55 Сейчас в теме
Мысль, куда направить силы: есть отдельная каста извращенцев (в том числе больших и корпоративных), которые держат код не в конфигураторе. Даже ходить далеко не надо: взять ту же конвертацию или алгоритмы трансляции во всяких (трибуквы)-финансах. Пишут код в блокнотике, суют его в справочник, потом в конфе где-нибудь видим: Выполнить(Ссылка.ТекстАлгоритма)

И вот тут-то можно и развернуться с новшествами в языке: кодер бьёт код на вашем чудо языке, некоторый чудо-транслятор где-то в фоне "компилит" это в инструкции на чистом 1Се, который потом исполняется, собственно, платформой.

Честно, я был бы счастлив иметь возможность писать в конвертации хотя бы процедуры :)

PS. извращенцы были в хорошем смысле слова, хотя и плеваться иногда на них охота.
Haimdell; lustin; +2 Ответить
44. zavedeev 16.12.16 09:35 Сейчас в теме
45. DoctorRoza 17.12.16 15:16 Сейчас в теме
+ в карму! Только один вопрос, просвятите - зачем ООП в 1С? Что нельзя написать и какой профит на выходе?
46. ineshyk 18.12.16 20:51 Сейчас в теме
Поставил +.
Но как такое юзать в продакшене?

И не может классическое ООП реализовать через интерпретаторы, кем 1с, собственно, и является.

48. spacecraft 19.12.16 15:37 Сейчас в теме
(46)
И не может классическое ООП реализовать через интерпретаторы, кем 1с, собственно, и является.

главное чтоб python об этом не узнал, а то работать перестанет. Да и php вместе с js.
Про "интерпретатор 1С" промолчу.
49. ineshyk 20.12.16 01:54 Сейчас в теме
(48) Ну в js жалкое подобие ООП.

А об "Про "интерпретатор 1С" промолчу." - так Вы не молчите.
50. ture 606 20.12.16 09:27 Сейчас в теме
(49) он просто не забивал голову.
47. ture 606 19.12.16 15:26 Сейчас в теме
(00) Выбор эксперта?

Новый макдиггер это!
51. ture 606 22.12.16 13:39 Сейчас в теме
(0) помнишь, я говорил, что не интересно и избегают? еще есть ощущение, что я не хотел тебе помочь? Последуй совету.
60. Evil Beaver 8100 18.03.17 10:05 Сейчас в теме
А я вот не освоил Го, задач как-то нет под него. Но любопытный язык, да
66. pvlunegov 157 15.11.17 08:05 Сейчас в теме
С комментариями согласен. Реализация ООП не стоит того, чтобы писать километры кода ради маленького функционала.
Неочевидно, трудно поддерживаемо другими разработчиками, визуально не читаемо.

Автор,
Чтобы код легко читался на интуитивном уровне, нужно как минимум изучить Питон, посмотреть Го.
Пытаться реализовать ООП в виде С++ на 1с нет смысла, потому что когда нет нативной поддержки от платформы будут ГРАБЛИ и КОСТЫЛИ.
Писать такой код тяжело и непотребно, он некрасив и неинтуитивен.

Почему так любят С++, потому что в свое время он был лаконичен, краток и красив (на английском языке).

Для русского языка код С++ не красив, потому что автор - англичанин с английскими образами и понятиями.

Чтобы код программы С++ был как минимум лаконичен и читаем непрограммистами, в вашем случае нужно :
1. Разделить интерфейс классов и реализацию на отдельные файлы.
2. Логически разделить отдельные классы на подклассы. Один класс реализует работу с пользователем, другой - внутренние механизмы работы с графической системой, вводом-выводом.
Третий класс - работу с другими классами.
3. Работа с пользователем должна быть реализована в классе в котором функции реализуют естественные команды на живом языке.
Например
функция повернуть_влево()
функция увеличить_ход()
функция сохраниться() - вызывает функции интерфейса внутреннего класса который реализует сохранение данных на диск и т.п.
функция дать_отчет() - формирует контекст получения данных, формирует пакет данных и выводит отчет.

Такой класс реализует инкапсуляцию внутренних методов во внутренних классах.
Пользователь системы, который видит ее в 1 раз видит:

1. Простые методы, простые классы, читаемые функции естественно понятные.
2. Если захочет, может залезть в реализацию и прочитать как оно сделано.

Эта концепция кстати, во всех серьезных книгах по С++ рассказывается авторами как азбука ООП.
Это не входит в парадигму ООП но является ДЖЕНТЕЛЬМЕНСКИМ навыком программирования.
67. IntelInside 128 16.11.17 13:14 Сейчас в теме
(66)
(66)
Относительно синтаксиса реализации ООП. Язык 1С называется 1С-Бейсик. Поэтому я и пытался делать "по-бейсиковски", а не "по-питоновски".

Относительно читабельности\писабельности кода не-программистами. Эта теория 60-х годов прошлого века является утопией. Программист - это профессия и у него должны быть профессиональные знания, навыки и инструментарий. Не будет ООП понятен "и домохозяйке", как и принципиальная электрическая схема ее любимого гаджета. Увы.

Относительно поддержки "в платформе". Вы просто не поняли смысл этой статьи. Я еще в прошлой удивлялся, что поддержка в платформе есть, но разработчики 1С ее "не дают". Никто мне тогда внятно так и не ответил на вопрос "почему?". Вот я взял и просто практически доказал что полноценный ООП в 1С возможен даже без каких-либо изменений в коде платформы. Точнее было бы сформулировать "без желания руководства 1С будут грабли и костыли".

И кстати я нашел ответ на вопрос "почему?". На хабре оказывается есть статья от 1С в которой описана политика 1С в отношении языка. Он оказывается сознательно ограничен в функциональности. СОЗНАТЕЛЬНО! <Это своеобразное сочетание мощной платформы и разумно-ограниченного прикладного языка>

А относительно работоспособности компоненты... Сами посудите - больше года после пререлиза компоненты прошло, а она работоспособна. В очередных релизах платформы ее не "запретили". Она им не мешает. Она 1С-непротиворечива. Другой вопрос, что "сознательно ограниченные в языковых возможностях" 1С-ники ее толком не понимают и применить не знают куда. Это действительно беда.

А собственно об ООП я, извините, в дискуссию ввязываться не хочу. С моей стороны это будет не гуманно.

Посмотрите еще здесь: https://forum.infostart.ru/forum9/topic178313/
68. pvlunegov 157 16.11.17 14:53 Сейчас в теме
(67) Если обидел, извините. НЕ хотел порочить вашу работу.
Работа хороша, эпична, мощна.
Я просто вставил свои замечания. И вот почему.
1. Я за более 10 лет работы в 1с для себя лично выявил и придерживаюсь простых правил.
а. Нет такого кода, который нельзя было бы улучшить, причесать, надраить, вылизать, сбрызнуть одеколоном.
б. Любой код должен стремиться к красоте, интуитивности, приятности, читабельности.
Это общее стремление любых живых мыслящих организмов - к самоорганизации.
в. Когда программист перестает причесывать код, он покрывается пылью, гарью и спустя года перестает работать, потому что любая система - живая и ее нужно поддерживать (сдувать пыль, перетасовывать и т.п.)
г. Любой список из более чем 3 пунктов плохо читабелен (интуитивно, подсознательно).
Из этого простое правило - превращать любой плоский код, состоящий из большого количества процедур (независимых), в Дерево фунций и процедур (вложенных), который разбиты на файлы, модули и папки.
Каждая папка, модуль и функция в конце концов должны подчинятся правилу САМОДОКУМЕНТИРУЕМОСТИ.

Правило САМОДОКУМЕНТИРУЕМОСТИ:
1. как можно меньше комментариев (в идеале вообще без оных)
2. Названия функций точно и максимально лаконично (без потери смысла!) отражают свой функционал

Если вы внимательно задумаетесь над вышесказанным и ОСОЗНАЕТЕ оное, то поймете, что вашу документацию можно и нужно переделать к САМОДОКУМЕНТИРУЕМОСТИ
а ваш код разбить на Деревья.
69. trustasia 14 30.03.19 17:51 Сейчас в теме
Чем дело продолжилось? Вопрос не праздный, хотел с Вами связаться по практическому применению.
Оставьте свое сообщение