Упражнения на Перфоленте. Парсим технологический журнал 1С

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

Чем только не парсят технологический журнал 1С. Есть и решения от 1С, есть и множество самописных конфигураций, обработок и скриптов на самых разных языках.

Подтолкнула меня к экспериментам статья Go. Разбор лога технологического журнала. Достойная альтернатива perl’у

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

Тем более, что я недавно опубликовал демонстратор языка программирования Перфолента и время мне позарез необходимо на его отладку и развитие.

Итак, поехали… Для начала, мне очень понравилась картинка в указанной статье, демонстрирующая многопоточную обработку файлов ТЖ (здесь и далее ТЖ равно «технологический журнал») и я решил, что и на Перфоленте попробую сделать похожую структуру программы. Затем, сделал вывод, что мне не хочется изобретать и использовать массу параметров командной строки. Проще сделать копию программы для другого отбора и обработки строк, ведь исходный код всегда под рукой. Постепенно накопятся все необходимые мне варианты.

Начало программы стандартное, нажимаем меню ШаблоныПрограмма и получаем начальный шаблон, где необходимо ввести имя программы:

 

//***************************
#ИспользоватьСтандартнуюБиблиотеку
Программа ПарсерТЖ
    //—————————
    Процедура Старт

    КонецПроцедуры
КонецПрограммы    

 

Теперь в процедуре Старт начинаем писать код. Нам необходимо обработать все файлы логов ТЖ находящиеся в папке программы. При необходимости, можно указать и другой каталог. Обрабатывать файлы будем в многопоточном цикле ДляКаждого, который использует все имеющиеся ядра процессора.

 

   //выбираем все лог файлы из текущей папки
   //загрузим все ядра процессора
   Рез=ПараллельныеДействия.ДляКаждого<Файл>(
                   ФС.ВыбратьФайлы(ЭтаПрограмма.Каталог,"*.log"),
                   ПолучитьДелегат(,ОбработатьФайл,"ДействиеПроц<Файл>"))

 

В указанном фрагменте кода для программистов 1С может быть не понятным оператор ПолучитьДелегат, который просто возвращает ссылку на процедуру с одним параметром, в которой и будет обрабатываться каждый файл.

Синтаксис оператора ПолучитьДелегат такой:

ПолучитьДелегат( Объект , ИмяМетода, "ТипДелегата")

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

 

Напишем эту процедуру чуть ниже процедуры Старт:

 

    //—————————
    Процедура ОбработатьФайл(Ф тип Файл
    
        Ив = Новый ИнтервалВремени
        
        Чт = Новый ЧтениеТекста(Ф)

        Пт = Новый ПостроительТекста

        Кво=0
        Цикл 
            Стр=Чт.ПрочитатьСтроку
            ПрерватьЕсли Стр Это Неопределено
            
            //началом строки события считаем шаблон #k8SjZc9Dxkdd:dd.d+
            //однако проверка только разделителей вполне надёжна и достаточна
            Если Сред(Стр,3,1)=":" И Сред(Стр,6,1)="." 
               Если Пт.Количество <> 0
                   Кво++
                   ОтборСтрок(Пт.ВСтроку)
               КонецЕсли    
               Пт.Очистить
            КонецЕсли
            Пт.Добавить(Стр)
        КонецЦикла
        Если Пт.Количество <> 0
            Кво++
            ОтборСтрок(Пт.ВСтроку)
        КонецЕсли    
        
        Чт.Закрыть
        
        ВыводСтроки "Обработали файл: "+Ф+"  Количество строк = "+Кво+"  Время, сек: "+Ив.ВсегоСекунд
        
    КонецПроцедуры    

 

Готово… Теперь наши файлы обрабатываются и для каждой строки вызывают процедуру ОтборСтрок(ТекущаяСтрока). Объект ПостроительТекста используем для ускорения конкатенации строк. Объект ИнтервалВремени используем для измерения времени обработки файла. Строки приходится склеивать потому, что в файле ТЖ могут быть многострочные фрагменты в определении одного события. Формально, в ТЖ события заканчиваются символами ВКПС, а многострочные строки разделяются символом ПС, но, к сожалению, для объекта ЧтениеТекста это одно и то же.

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

Процедура получилась простая:

 

    //—————————
    //В этой процедуре отберем только интересующий нас вид строк
    Процедура ОтборСтрок(Стр тип Строка
        Если Найти(Стр,ФильтрСобытия)=0
            Возврат
        КонецЕсли
        Если ИспользоватьФильтрДанных И Найти(Стр,ФильтрДанных)=0
            Возврат
        КонецЕсли
        ОчередьСтрок.Добавить(Стр)
    КонецПроцедуры   

 

Как видно, мы используем в виде накопителя отобранных строк некий объект ОчередьСтрок, а так же еще несколько имен: ФильтрСобытия, ФильтрДанных, ИспользоватьФильтрДанных. Это всё поля, которые мы определили в модуле Программа:

 

Программа ПрасерТЖ

    Поле ФильтрСобытия тип Строка = ",SDBL,"
    Поле ФильтрДанных тип Строка = "Context=" 
    Поле ИспользоватьФильтрДанных тип Булево = НЕ ФильтрДанных.Пустая

    Поле ОчередьСтрок тип Очередь<Строка> = Новый Очередь<Строка

 

В Перфоленте у объектов есть Поля, которые похожи на переменные модуля 1С, но все же это не переменные, переменные в Перфоленте «живут» только в методах.

Объект ОчередьСтрок используется одновременно несколькими потоками, добавляющими в него отобранные строки. Если бы это была обычная коллекция, то могли бы возникнуть проблемы. Многопоточность опасна, если разные потоки одновременно обращаются к одним и тем же данным. Однако, в Перфоленте многие коллекции обобщенного типа, в том числе и Очередь<>, являются потокобезопасными и поэтому ни какая дополнительная синхронизация нам не потребуется.

 

На данном этапе у нас уже есть коллекция отобранных строк для события SDBL. Запустим их многопоточную обработку и посчитаем суммарное время работы для каждого контекста выполнения.

 

       
       
//обработаем все найденные строки
       Рез=ПараллельныеДействия.ДляКаждого<Строка>(
                   
ОчередьСтрок,
                   
ПолучитьДелегат(,ОбработатьСтроку,"ДействиеПроц<Строка>"))

 

Ничего нового по сравнению с обработкой файлов в этом фрагменте кода нет, разве что тип Файл сменился типом Строка.

Напишем процедуру окончательной обработки строки лога:

 

    //—————————
    //Получим из строки интересующие нас данные
    Процедура ОбработатьСтроку(Стр тип Строка
        
//получим длительность события
        Длительность = Число(Стр.Сред("-",","))
        
        
//получим контекст
        //Контекст = Стр.Сред("Context=’","’")
        
        
//а можно воспользоваться и регулярным выражением
        Контекст = ""
        
Рег = Новый РегулярноеВыражение("(?<=Context=’).*?(?=’)")
        
Если Рег.Совпадает(Стр)
            
Контекст=Рег.НайтиСовпадения(Стр)[0].Значение
        КонецЕсли
        
        
        
//нам все же понадобится блокировка, т.к. несколько потоков могут одновременно попытаться увеличить значение по одному и тому же контексту

        Блокировка ОчередьСтрок
            //сложим время одинаковых контекстов

            Было = Результат.Получить(Контекст)
           
Результат.Вставить(Контекст, Было+Длительность)

        КонецБлокировки

      
    
КонецПроцедуры  

 

Как мне кажется, этот код будет понятен всем программистам 1С. Отбор фрагментов строки можно осуществлять двумя способами, обычными функциями работы со строками и регулярными выражениями. Кому что больше нравится.

Результат в этот раз мы собираем в коллекцию типа Соответствие<Строка,Число>. Выглядит немного необычно для программистов 1С, но не для программистов C#. В данном случае, мы просто указываем, что ключ соответствия будет иметь тип Строка, а значение будет иметь тип Число. Другие типы в этой коллекции сохранить нельзя. Можно ли использовать обычное Соответствие? Можно, но скорость его работы будет меньше и понадобятся блокировки, т.к. обычное Соответствие не является потокобезопасным.

 

    Поле Результат тип Соответствие<Строка,Число> = Новый Соответствие<Строка,Число

 

Осталось обработать результат. А давайте сохраним его в файл Эксель и откроем.

 

      
       
//обработаем результат, например, создадим табличку
       Док=Новый ТабличныйДокумент
       НомСтр=1; 
       
Для КлючЗнач Из Результат
           //берем только длительные события
           ПродолжитьЕсли КлючЗнач.Значение<400000 
           
Док.УстановитьЗначениеЯчейки(НомСтр  , 1,КлючЗнач.Значение
           
Док.УстановитьЗначениеЯчейки(НомСтр++, 2,КлючЗнач.Ключ
       
КонецЦикла

       //сохраним и откроем в Экселе
       Док.Записать(ЭтаПрограмма.Каталог+"ТабличныйДокумент.xlsx") 
       
ЗапуститьПриложение(ЭтаПрограмма.Каталог+"ТабличныйДокумент.xlsx")  

 

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

 

А что со скоростью?

Вполне сопоставимо со скоростью программы на Go, у меня даже быстрее получилось, но не факт, что на любом компьютере будет так же. Тестовый файл размером 5,7 ГБ, около 10 млн. строк, пережевался за 5 минут.

 

А что с потреблением памяти и допустимым размером файлов лога?

Во время обработки файла размером 5,7 ГБ максимальное потребление памяти программой составило 1,2 ГБ. Файлы больше указанного размера я не проверял, но скорее всего проблем не будет.

 

Как мне кажется, любой программист 1С сможет самостоятельно доработать этот пример, добавив необходимые отборы, сортировки и группировки.

58 Comments

  1. Evil Beaver

    У вас Если без Тогда? т.е. переносить операции на другую строку уже нельзя?

    Если А = 1 и
    БольшоеСложноеДействие() // это все еще выражение условия?
    В = 3; // а это тело условия?
    КонецЕсли;

    И что такое «ПродолжитьЕсли»? Такое есть в VB.NET? Я в C# не встречал

    Reply
  2. Perfolenta

    (1) можете смело писать Тогда, оно просто не обязательное… можете переносить так как написали в своем комментарии, хотя я больше люблю, что бы И было не в конце строки, а в начале следующей…

    да, ПродолжитьЕсли это оригинальный оператор Перфоленты…

    еще есть:

    ПрерватьЕсли Условие

    ВозвратЕсли Условие

    можно и с пробелом:

    Прервать Если Условие

    Возврат Если Условие

    Reply
  3. Evil Beaver

    Кажется перфоленте не хватает описания формальной грамматики языка где-нибудь в открытом доступе. А то читаешь и удивляешься чего только не надо будет узнать…

    P.S. я пожалуй пока останусь при своем мнении, что это совсем другой язык, даже не «похожий на 1С», и учить его не полезнее, чем сразу учить C#. Я могу ошибаться.

    Reply
  4. Perfolenta

    (3) это верно, я файл документации только на четверть написал… надеюсь, как и обещал к новому году выкатить…

    Reply
  5. Perfolenta

    (3) для начала можно просто по 1с-ному писать… постепенно узнавая что-то новое… я не думаю, что у вас лично возникла проблема с пониманием хотя бы одной строки кода…

    а для чистых 1С-ников да, есть новинки, но не так много, что бы нельзя было понять их смысл… а как иначе привнести в язык современные новинки?

    Как прикажете записать кортежи не меняя синтаксис 1с? пришлось менять… старался осторожно подходить, что бы не слишком страшно выглядело…

    Reply
  6. Evil Beaver

    (5) Нуу… я в уме переводил на шарп или на VB. Но это как раз говорит о том, что когнитивная нагрузка языка довольно большая. А чисто по 1С-ному разве можно? У вас же строгая типизация, переменные объявлять надо.

    Reply
  7. Perfolenta

    (6) объявлять типы обязательно только для полей, свойств и в сигнатурах методов… переменные можно все неявно инициализировать, как и делают в 1с чаще всего… я сначала начинал делать то, что получилось у вас, но потом понял, что ни как не впишусь в рамки 1С и начал «реформу» языка, старая сохранить наследственность от 1С, но не более того…

    Reply
  8. Evil Beaver

    (7) ну потому что MSIL и CLR рассчитывают на строгую типизацию, поэтому я на ранних этапах забросил идею компиляции в MSIL или использования LLVM

    Reply
  9. Perfolenta

    (8) вам повезло 🙂 я не ожидал того объема работ, который пришлось и еще предстоит сделать… там еще и подводных камней оказалось предостаточно… документация Microsoft та еще штучка… особенно обидно, когда что-то делаешь, а потом натыкаешься где-то на сноску мелким шрифтом и понимаешь, что делал все не правильно…

    Reply
  10. Steelvan

    (3) со вторым абзацем согласен

    В прошлом году тоже «новый» язык оприлюдили.

    РусскийФокс называли.

    Что-то автор перестал его продвигать в массы после нескольких публикаций.

    Reply
  11. Steelvan

    Надо быстрее делать решения, которые решают важные для дельцов задачи.

    Это может дать деньги для жизни за счет проекта + будут примеры использования на настоящих деловых задачах.

    Иначе сообщество может Вас забросать бесплатными работами на 10 лет вперед.

    Вы выдохнетесь (жена запилит, просто надоест и т.п.) и бросите.

    Пока это просто «смотрите что могу». Поделка.

    До продукта нужна обертка в сайт с разделами:

    *) Примеры применения;

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

    *) Ссылки на выполненные работы с выгодой по сравнению с 1С;

    *) Форум техподдержки;

    Может и прозвучит грубо, но мое мнение такое, что автор это сделал для самовыражения.

    Если бы он хотел этим зарабатывать, то доделал и выкатил бы сразу полный комплект сопутствующей атрибутики (сайт, примеры, документация). И это было бы воспринято серьезно с самого начала.

    Обнародование «как есть, разбирайтесь сами» признак того, что это побарахтается немного и повторит судьбу onescript (будет пущено на самотек с доработками сообщества и минимальным участием авторов как регуляторов).

    Прошу привести пример, что я могу сделать на этом, чего не могу на 1С сервере.

    Причем это должен быть действительно убедительный аргумент с учетом того, что у 1С очень большая фора. Ну ооочень большая.

    Нужны практические примеры применения, за которые хоть кто-то заплатил копейку.

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

    Все вышенабранное является личным мнением автора и может отличаться от мнения редакции 🙂

    Reply
  12. Steelvan

    Деньги двигатель всего.

    На этом можно зарабатывать ?

    Если да, то отлично.

    Если нет, то вы у своей семьи украли КолВоЧасов * 1000руб (+/-).

    Reply
  13. Perfolenta

    (10) я общаюсь с автором Русского Фокса, он изначально утверждал, что для себя его делает… и он продолжает его делать, выкладывает ролики в Ютубе…

    на мой взгляд у него одна проблема, Майкрософт бросила Фокс, совсем…

    А Net пока ни кто бросать не собирается, более того, планы его развития изложены на годы вперед… так что мне на этот счет легче, чем Андрею Ошнурову…

    я вовсе не питаю иллюзий, что мне удастся пробить недоверие… но, судя по большинству комментариев тех, кто скачал и посмотрел мой язык, люди приняли Перфоленту хорошо…

    и это радует… а дальше от меня будет зависеть, смогу ли я сдела так, что бы люди хотели и им нравилось программировать на Перфоленте… буду стараться…

    Reply
  14. Perfolenta

    (11) да, вы все верно написали… без какой-то схемы монетизации всё будет жить и двигаться плохо… на грани выживания…

    но для того, что бы двинуться в бизнес нужен продукт, а его сначала сделать надо… вот и делаю…

    изначально я тоже думал, что лучше выкатить уже готовый продукт… но после нескольких экспериментов над 1с-никами, которые согласились попробовать Перфоленту (до опубликования), я понял, что знакомить людей с новым языком можно заранее… это работает… люди попробовали и стали делать для себя маленькие, но полезные программки… конечно, с моей помощью, но начали и у них получается, всё работает…

    язык и коммерческий продукт на его основе это все же разные вещи…

    Что вы можете сделать из того, что не можете на 1С?

    Много чего, например, скорость работы кода Перфоленты может в сотни раз превышать скорость работы 1С… можно сделать службу Windows, независимое от лицензий 1С приложение, собственно всё, что делают люди выбирая C# или VB вместо 1С…

    Reply
  15. Perfolenta

    (12) я это хорошо понимаю, поэтому думаю о том, как продукт будет монетизироваться… но на данный момент продукт еще доделать надо… пока был только анонс, что не противоречит практике маркетинга…

    а у семей, в капитализме, все самозанятые вынуждены время красть, к сожалению…

    я не могу себе позволить уйти с работы в 17-00, как это делали мои родители в СССР, или уйти в отпуск на 30 дней, абсолютно не вспоминая о работе, как это делал мой отец…

    Reply
  16. Perfolenta

    (6)

    А чисто по 1С-ному разве можно? У вас же строгая типизация, переменные объявлять надо

    Сегодня, ради проверки ответа на ваш вопрос, я взял библиотеку для OneScript под названием TRun1C, думаю знаете такую… в ней 1921 строка кода… прилично…

    У меня ушло примерно 20 минут, что бы превратить ее в DLL библиотеку!

    Ушло бы и меньше, но я же не автор библиотеки, так что на беглое изучение кода потратился…

    Я только обернул ее в класс, прописал типы в сигнатуры методов и еще несколько мелочей, вроде замены слова Экспорт на атрибут &ВидноВсем… и все, библиотека нормально откомпилировалась и заработала…

    т.е. в самих методах мне почти ничего не пришлось менять… все по односкриптному осталось…

    Вывод… для начала вполне можно писать по одинэсному, изучив минимальные требования к оформлению программы… и прочитав немного о переменных и типах, например тут http://promcod.com.ua/subcat.asp?cat=perfolenta-programmig-language&subcat=perfolenta-syntax

    Reply
  17. vasvl123

    (11) На 1С чего не пытаешься сделать, только учетная система получается)

    Reply
  18. vasvl123

    (12) А если в рабочее время, то обокрали работодателя

    Reply
  19. Perfolenta

    (17) это точно!!!

    Reply
  20. Perfolenta

    (18) я, к счастью, сам себе работодатель… хотя, если разобраться, то клиенты это тоже начальники и работодатели… только они не имеют возможности тебя уволить, но могут уволиться сами..

    Reply
  21. Perfolenta

    Только что проверил интересный момент: оказывается, C# и VB.Net не умеют делать цикл Для Каждого (foreach) по нескольким перечислителям, а Перфолента умеет!!!

    Например, в стандартной библиотеке Перфоленты есть тип Матрица, который можно обойти в цикле Для Каждого двумя способами: по значениям и по элементам матрицы.

    Для Значение тип ДВещ Из МояМатрица //цикл по IEnumerable<ДВещ>
    //
    КонецЦикла
    Для Элемент тип ЭлементМатрицы Из МояМатрица  //цикл по IEnumerable<ЭлементМатрицы>
    //
    КонецЦикла
    

    C# и VB.Net могут только первый перечислитель обойти по значениям, а второй не могут….

    вот такой вот курьёз 🙂 кое в чем Перфолента круче, хотя пока, конечно, в ней еще многого нет, что есть в этих двух языках… только работаю над многими вещами…

    Reply
  22. Darklight

    (5)Простите, а где у Вас здесь продемонстрирован кортеж?

    Reply
  23. Perfolenta

    (22) это к слову пришлось… пример с кортежами есть в дистрибутиве…

    выглядят кортежи примерно так:

    к3 = $(400,»Hello_5″)

    или вот функция возвращающая кортеж:

    Функция ПолучитьКортежValueTuple() тип $<Целое,Строка> //работает
    
    Возврат $(200,»Hello_2″) //работает
    
    //и более длинные варианты того же самого:
    
    Возврат $<Целое,Строка>(200,»Hello_2″) //работает
    Возврат Новый $<Целое,Строка>(200,»Hello_2″) //работает
    Возврат Новый ValueTuple<Целое,Строка>(200,»Hello_2″) //работает
    Возврат ValueTuple.Create<Целое,Строка>(200,»Hello_2″) //работает
    
    КонецФункции

    Показать

    Reply
  24. minimajack

    (21) чесно говоря ничего не понял…хотя пытался)

    Reply
  25. Darklight

    (8)Зря забросили идею компиляции в LLVM

    Есть языки с динамической типизацией, имеющие компилятор в LLVM (ну если я не ошибаюсь — я тут пока профан, но тема мне очень интересна), например JavaScript, Python, Ruby

    Вот тутесть небольшая статья «Динамическая компиляция программ на языке JavaScript в статически типизированное внутреннее представление LLVM»

    Хотя я лично за языки со статической типизацией (и верю что будущее развития языка платформы 1С Предприятие именно в статике) — но и динамические тоже нужны — особенно для скриптов и макросов, но если они ещё и компилятор в LLVM получат — так вообще очень круто выходит — за LLVM будущее!

    Reply
  26. Perfolenta

    (24) значит цикл Для Каждого вам не понятен… все просто, когда вы пишете Для Каждого система определяет по какому типу можно пройтись в указанной коллекции…

    например, когда вы идете по объекту СписокЗначений, то вы на каждом шаге получаете тип ЭлементСпискаЗначений…

    но в Перфоленте коллекция может давать возможность обходить ее по разным типам содержимого… представьте, что СписокЗначений можно было бы обойти сразу по значениям или по представлениям, а не только по элементам….

    Reply
  27. Darklight

    (23)Здорово! А именнованные поля кортежей поддерживаются? А деконструкция? А Свитчи?

    Reply
  28. Darklight

    (26)Дайте, пожалуйста, более наглядный пример — заинтриговали

    Reply
  29. Perfolenta

    (27) ну вы прям всё сразу от меня хотите 🙂

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

    деконструкция уже есть, но пока только в переменные и в массив… в цикле Для уже есть, но в опубликованном дистибутиве этого еще нет…

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

    с одной стороны хочется такой же мощный Select как на VB, но с другой стороны простинький как в С# мне тоже нравится… короче как остановлюсь на чем-то так и появится…

    Reply
  30. Darklight

    У вас вот этот код

    Рег = Новый РегулярноеВыражение(«(?<=Context=’).*?(?=’)»)
    

    Выполняется внутри процедуры «ОтборСтрок» которая вызывается циклически — это не очень хорошее решение — т.к. регулярне выражение каждый раз компилируется заново а это (в зависимости от выражения) может быть достаточно затратной операцией. Да ещё и объекты постоянно создаются заново — засоряя память и ускоряя процесс сборки мусора.

    Я не знаю насколько потокобезопасен класс «РегулярноеВыражение» но лучше его вынести за рамки потока — либо сделать глобальную коллекцию предкомпилированных паттернов (используемую всеми потоками) — либо сделать для каждого параллельного алгоритима отдельный экземпляр(ы) (что сложнее в силу применения параллельного цикла, где очень сложно управлять асинхронностью).

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

    Reply
  31. Perfolenta

    (30) вы прямо читаете мои мысли… я сначала вообще без регулярных выражений написал, а потом решил, что надо добавить пример с регулярным выражением… думал его вынести из процедуры, но потом решил, что так будет не наглядно… в производительности просадка копеечная, я проверял…

    Reply
  32. Perfolenta

    (28) вот на C#

    using System;
    using Промкод.Перфолента;
    
    namespace Энумерабле2
    {
    class Program
    {
    static void Main(string[] args)
    {
    Матрица matr=new Матрица(3,3);
    foreach (Double element in matr)
    {
    Console.WriteLine($»Element: {element}»);
    }
    foreach (ЭлементМатрицы element2 in matr) //ОШИБКА!!!
    {
    Console.WriteLine($»Element: {element2}»);
    }
    
    Console.ReadLine();
    
    }
    }
    }

    Показать

    то же самое на Перфоленте работает…

    Reply
  33. Darklight

    (29)Именованные поля очень полезны — я при работе с кортежами предпочитаю как раз с ними работать!

    Reply
  34. Darklight

    (31)Тут больше дело в показательноси хотя да, это палка о двух концах либо показывать как проще, либо показывать как нужно!

    Reply
  35. Darklight

    (32)Что-то пример какой-то не удачный. Всё равно мне не понятно

    Reply
  36. Perfolenta

    (35) что именно не понятно? есть коллекция, например, СписокЗначений как в 1С, его можно обойти в цикле Для Каждого получая на каждой итерации объект типа ЭлементСпискаЗначений из которого можно получить Значение….

    а было бы хорошо, если бы можно было сразу по значениям пройтись…

    вот в данном примере это и продемонстрировано…

    сначала проходим по значениям матрицы, которые имеют тип Double, а потом по элементам матрицы, которые имеют тип ЭлементМатрицы и содержат информацию о строке и колонке значения…

    в Перфоленте я так могу, а в C# и VB нет…

    Reply
  37. minimajack

    (36) это никому не надо, если надо — есть методы коллекций values(), keys() и т.п.

    Reply
  38. Perfolenta

    (37) надо или не надо это спорный вопрос… а вот собственные спецификации они криво реализовали это факт… у меня же работает, а я по ихним же спецификациям делал…

    Reply
  39. Perfolenta

    (34) наглядность и «синтаксический сахар» почти всегда побеждает соображения производительности, пока критически в них не упрется…

    Reply
  40. Perfolenta

    (33) может быть… хотя я обычно именование полей в кортежах не использую… у меня в программах кортежи это временные транзитные структуры.. а если надо долгоживущую, то я обычную структуру делаю..

    я обязательно именованные поля сделаю, но значительно позже… сейчас еще большой список задач, которые я считаю более важными…

    Reply
  41. minimajack

    (38)

    В СписокЗначений лежат ЭлементСпискаЗначений в котором значение типа ЭлементСпискаЗначений…

    Как выбрать Значение?

    СписокЗначений = Новый СписокЗначений;
    СписокЗначений.Добавить(1,»1″);
    СписокЗначений.Добавить(2,»2″);
    
    СписокЗначений2 = Новый СписокЗначений;
    
    Для каждого ключЗнач Из СписокЗначений Цикл
    СписокЗначений2.Добавить(ключЗнач, ключЗнач.Представление);
    КонецЦикла;
    
    Для каждого ключЗнач Из СписокЗначений2 Цикл
    Сообщить(Строка(ТипЗнч(ключЗнач)) + » » + ТипЗнч(ключЗнач.Значение));
    КонецЦикла;
    

    Показать

    Элемент списка значений Элемент списка значений
    Элемент списка значений Элемент списка значений
    Reply
  42. Perfolenta

    (41) вы про 1С или про Перфоленту спрашиваете?

    ответ в обоих случаях — никак…

    я пока двойной перечислитель только в объекте Матрица сделал… а СписокЗначений и другие 1с-ные коллекции почти такие же как в 1С… но думаю, что сделаю и в них тоже такую возможность… а может и не буду…

    Reply
  43. for_sale

    (15)

    Кем это они у вас так замечательно работали??

    И при чём тут капитализм? Я сейчас при капитализме ушёл на вольный хлеб — не нарадуюсь. В том числе и потому, что не надо никуда ездить, и работать можно, когда хочешь.

    Reply
  44. Fox-trot

    (43)

    И при чём тут капитализм?

    при социализме самозанятых почти не было, кругом работали от звонка до звонка

    такие дела

    Reply
  45. Perfolenta

    (46) такое впечатление, что вы про разницу между капитализмом и социализмом ничего не знаете…

    я бы и работал на заводе, был бы инженером кораблестроителем, на которого учился… только от него остались рожки да ножки… огромная территория на которой можно сталкера снимать… как и от остальных заводов и фабрик в городе… мне просто пришлось стать самозанятым в 90-е, что бы с голоду не помереть…

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

    Сейчас на заводе кое-что изменилось… наш завод, на полученную прибыль, построил целый микрорайон для своих рабочих, несколько пансионатов и пионерских лагерей на море для своих рабочих и их детей, он содержал несколько десятков технических и гуманитарных кружков и спортивных секций, где я мог заниматься бесплатно, выбирая то, что нравится… а сегодня, вся эта прибыль уходит хозяевам, которые имели ввиду и рабочих и их детей… именно поэтому народ у нас недавно собрал деньги и поставил памятник директору нашего завода, с говорящей фамилией Заботин… который, помимо всего остального, построил яхтклуб для нас, а не купил яхту себе, как делают нынешние…

    Reply
  46. Perfolenta

    (48) гниющий капитализм никуда не шагает… он гниет, как и 100 лет назад…

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

    Вы меня тут чуть ли не овцой обозвали и предложили миску супа… так вот, я открыл свою первую фирму в 1992-м, а сегодня у меня уже четвертая… я могу себе многое позволить, т.к. вполне достаточно зарабатываю на жизнь… и я прекрасно знаю, что такое эксплуатация людей, т.к. сам этим не мало занимался… но лет 10 назад я это прекратил, т.к. мне всегда это было противно… теперь моя фирма это семейное предприятие…

    Но глядя на многих моих друзей и знакомых, я понимаю, что их жизнь могла бы быть совсем другой, если бы остался Союз… я видел их семьи тогда, и я вижу как у них сейчас…

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

    съесть, то он съест, но кто ему даст… ваши слова напоминают речевки о походе в Европу на нашем украинском майдане… чашечка кофе с утра в парижском кафе по безвизу… ага… этот безвиз доступен очень не многим… а остальным только в виде «съездить в Париж и умереть»… вы прекрасно знаете, что 1% американцев владеет 82% богатства и не собирается ни с кем делиться…

    Reply
  47. Fox-trot

    (48)

    Вы даже не понимаете, что вы сами можете быть директором завода и строить яхтклубы (или покупать яхты), что вы можете вообще не работать и жить припеваючи

    вот он предел мечтаний

    ржунимагу

    Reply
  48. Perfolenta

    (27) сделал «свитчи» 🙂

    выглядит так

    Выбор [Для] <expr> :

    ( Когда <expr> [ПРИ <expr>] [, <expr> [ПРИ <expr>]] [ Тогда ] : <stmt>+ : )+

    [ Иначе : <stmt>+ : ]

    КонецВыбора

    работает…

    Для Инд=1 По 8
    
    Выбор Для Инд
    Когда 1,3,5 Тогда
    ВыводСтроки «Не четные»
    Когда 2,4,6 //ключевое слово Тогда не обязательное
    ВыводСтроки «Четные»
    Когда 35
    Тогда
    ВыводСтроки «Таких не бывает»
    Иначе
    ВыводСтроки «Больше 6»
    КонецВыбора
    
    КонецЦикла
    
    Для Инд=1 По 8
    
    //каждый блок в одну строку
    Выбор Инд //ключевое слово Для не обязательное
    Когда 1,3,5 Тогда ВыводСтроки «Не четные»
    Когда 2,4,6;      ВыводСтроки «Четные»
    Когда 35;         ВыводСтроки «Таких не бывает»
    Иначе             ВыводСтроки «Больше 6»
    КонецВыбора
    
    КонецЦикла
    
    Для Каждого Об тип Объект Из {5, 10, 15, «Привет», «А»с, «Ф»с, Истина, ‘20191231’}
    //а можно просто
    //Для Об Из {5, 10, 15, «Привет», «А»с, «Ф»с, Истина, ‘20191231’}
    
    //с дополнительным условием ПРИ
    Выбор ТипЗнч(Об)
    Когда Тип(«Целое») При Об>10,
    Тип(«Целое») При Об=10
    ВыводСтроки «Целое >= 10»
    Когда Тип(«Целое») При Об<10 Тогда
    ВыводСтроки «Целое < 10»
    Когда Тип(«Символ») При Об<«Я»с и Об>»О»с Тогда
    ВыводСтроки «Символ»
    Когда Тип(«Дата»)
    ВыводСтроки «Дата»
    Прервать //это прерывание цикла, а не выход из блока, как в C#!!!!
    Иначе
    ВыводСтроки «Другое значение: «+Об+» ТипЗнч=»+ТипЗнчСтр(Об)
    КонецВыбора
    
    КонецЦикла
    
    

    Показать

    Reply
  49. Darklight

    (59)Это хорошо!

    А свитчи-выражения?


    Когда 2,4,6; ВыводСтроки «Четные»

    Такая запись (с точкой запятой посреди оператра) выглядит очень непривычно и как-то не логично (даже не знаю — есть ли где-то ещё, в других языках такие конструкции — где точка с запятой может разделять секции одного оператора, хотя — конечно же такое есть — это цикл for например в c ++ (и некоторых других, схожих с ним языках) «for (int i = 1 ; i < 100; i++)» — но тут внутри скобок список из трёх отдельных выражений, а не одно семантическое выражение, разделённое на части через «;» — но мне никогда такая запись не нравилась — в Kotlin или Python это реализовано более изящно, но это лирика — речь не про циклы, а про применение «;» внутри одного оператора — ну очень коряво это, на мой взгляд.

    А по поводу свитчей — всё же посмотрите лучше в сторону Kotlin и его оператора «when»

    Reply
  50. Perfolenta

    (61)

    Такая запись (с точкой запятой посреди оператра) выглядит очень непривычно и как-то не логично

    ну почему же не привычно… на языке 1с в одну строку именно через точку с запятой и пишут… точка с запятой может использоваться везде где нужен разделитель… кстати, в данной конструкции ее можно было даже и не ставить, я просто тестировал разные варианты написания…. компилятор Перфоленты в большинстве случаев прекрасно переваривает отсутствие ;

    А свитчи-выражения?

    не понял что вы имеете ввиду? в моем предыдущем комментарии, в самом начале, там где формальное описание, <expr> означает выражение…

    А по поводу свитчей — всё же посмотрите лучше в сторону Kotlin и его оператора «when»

    смотрел я… ничего особенного не увидел… по-моему, в C# и в Vb даже мощнее, чем в Котлине… если не считать функциональной формы оператора when, когда возвращается результат… может быть такую тоже сделаю… а, понял… вы, наверное, это и имели ввиду, спрашивая про свитчи-выражения?

    кстати… в Перфоленте функциональную форму котлиновского оператора when частично заменяет оператор ?(условие1, результат1, условие2, результат2 …, условиеN, результатN, результатИначе)

    Reply
  51. Darklight
    Reply
  52. Perfolenta

    (63)

    Хотя я сам уже знаю ответ («если а = 1 тогда б=1; иначе б=2 конецесли»

    Вы сами ответили на свой вопрос… а теперь уберите отсюда слово Тогда, которое в Перфоленте не обязательно и поймете, почему я в тесте поставил в похожем месте ;

    просто для визуального разделения… компилятор и без нее поймет, но в записи в одну строку слово Тогда лучше не пропускать, с ним красивее…

    кстати, спасибо, благодаря вам обнаружил, что при записи в одну строку компилятор Перфоленты тоже требует ; перед Иначе, хотя везде я старался сделать что бы и без ; понимало, но тут пропустил…

    я не любитель писать в одну строку, я люблю форматирование вниз, а не влево…

    синтаксис преобразился и стал очень похож на Kotlin

    и Котлин и Шарп наследники синтаксиса Си, поэтому не удивительно, когда они приходят к похожим решениям…

    но Перфолента наследует синтаксис 1С, поэтому я не могу делать его Си-подобным и не хочу…

    я просто пытаюсь здравые идеи других языков красиво выразить в синтаксисе Перфоленты…

    например, благодаря вам, я решил, что надо добавить оператор В (in), я и раньше о нем думал, но теперь пришел к мнению, что он точно будет…

    еще, задумался над необходимостью диапазонов 1..10, может тоже сделаю, но еще не решил… надо определиться какие операции будут доступны с диапазонами и что они из себя внутренне будут представлять…

    Спасибо за ваши советы, они заставляют думать о том, о чем не думал до этого… вы уже повлияли на развитие Перфоленты 🙂

    Reply
  53. Darklight
    Reply
  54. Perfolenta

    (65) на данный момент у меня два основных требования:

    1) Перфолента это расширение языка 1с, т.е. код написанный по правилам языка 1С должен работать с минимальными переделками…

    2) Все, что есть в Net должно вызываться…

    а дальше идут не требования, а просто вкусовые предпочтения:

    3) я не люблю обилие значков и предпочитаю ключевые слова…

    4) я не люблю полностью функциональные языки… мне нравится только функциональный подход в некоторых конструкциях… поэтому я скрещиваю императивный и функциональный стиль, но осторожно…

    5) минимизация сложных для беглого чтения конструкций…

    От полей я не откажусь, т.к. они есть в Net и особых проблем не вызывают… а вот защиту от неопределенности обязательно буду развивать…

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

    Reply
  55. Darklight
    Reply
  56. Perfolenta
    Reply
  57. Darklight
    Reply
  58. Perfolenta

    (69)

    и сейчас я вообще вынашиваю планы о разработке совершенно иного императивного языка

    я желаю вам удачи, но могу сказать, что сам просто не представлял объем работы необходимый для создания современного языка… теперь представляю… а ваша задумка грандиознее моей, так что готовьтесь… 🙂

    пройдёт ещё лет 30

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

    Возможно русский синтаксис сохранят, а может и нет…. не так уж много программистов кому он действительно нужен!

    много таких, кому нужен… особенно, если убрать комплекс неполноценности… думаю через годик устроить бои с программистами Шарпа, кто быстрее и понятнее напишет решения задач… думаю, что Перфолента не плохо себя покажет… конечно, для этого надо будет уравнять шансы и писать код в одинаковом редакторе… с Visual Studio мне пока ни как не потягаться…

    их будут манить мощные и изящные фишки более активно развивающихся языков, ну и их востребованность (и как следствие — деньги и количество вакансий)

    у языка 1с фишек нет, а вакансии есть… это не прямая корреляция… реклама и маркетинг больше влияют на развитие и распространение языка, чем любые его фишки… вспомните классику «написано однажды — работает везде» и сколько бабла на раскрутку этого слогана было потрачено…

    да и сколько раз за 30 лет я слышал о новых крутых парадигмах и языках, но если честно, то большинство кода в мире пишется на обычных циклах и условных операторах… мало чем отличающихся от старых… достаточно примеры в GitHabe посмотреть на том же Шарпе…

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *