Имя: Пароль:
1C
1С v8
Использование функций вместо процедур. Подмена понятий или..?
,
0 lxs
 
23.12.19
17:10
1. Следует строго разграничивать proc(x) и func(x) 44% (12)
2. Свой вариант 44% (12)
3. Без разницы, говнокод - наше всё 11% (3)
Всего мнений: 27

Приветствую всех.

Некоторое время назад довелось заниматься code review команды разработчиков.
Наткнулся на то, что в коллективе была принята методология использования вызова функций вместо процедур независимо от того, возвращает ли что-то данная функция или нет.

То есть код

РассчитатьЗадолженность(); //где РассчитатьЗадолженность() - функция

Повсеместно.

У кого какой опыт, кто какой методологии придерживается? Может быть я консервативен, но зачем использовать не по назначению конструкции?
144 vi0
 
25.12.19
08:28
(143) или чтобы эскалировать исключение после его обработки https://its.1c.ru/db/v8std#content:499:hdoc
145 Сияющий в темноте
 
25.12.19
09:07
начнем с того,чтотв теории есть входные параметры,есть выходные,а есть изменяемые,которые входные и выходные сразу.
1с не javascript,где только один выходной параметр.

и когда мы в процедуру передаем флаг "отказ",то это можно рассматривать,как возвращаемое значение

а есть ли разница?
Процедура ЧтоТоСделать(Результат,Параметры)
Функция РезультатВыполненияЧегоТо(Параметры)

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

не забываем,что многие ошибки можно корректно в коде обработать,чтобы пользователь их не заметил.
исключения же хороши тогда,когда ошибка фатальна,и продолжить работу,в принципе,нельзя,как и пытаться эту ошибку обработать.
146 Дык ё
 
25.12.19
09:22
а еще функцию можно вызвать из табло

Свой вариант
147 vi0
 
25.12.19
09:41
(145) > а есть ли разница?
Конечно есть - функция создает новую сущность - возвращаемое значение, а в процедуре ты меняешь окружение, и еще неизвестно насколько качественно.
148 mzelensky
 
25.12.19
09:54
(147) Это где такое написано?
149 mzelensky
 
25.12.19
09:57
(147) Я достаточно давно уже пишу вот так:

Функция МояФункция(ВходящийПараметр1)

   РезультатФункции = новый Структура();
   РезультатФункции.Вставить("ВыполненоУспешно", Истина);
   РезультатФункции.Вставить("ВыходнойПараметр1", Неопределено); //При необходимости
   РезультатФункции.Вставить("ВыходнойПараметр2", Неопределено); //При необходимости

   Попытка
      ...
   Исключение
      РезультатФункции.ВыполненоУспешно = Ложь;
   КонецПопытки

   Возврат РезультатФункции;

КонецФункции
150 vi0
 
25.12.19
10:01
(148) что именно написано? я говорю по факту. C чем конкретно ты не согласен?
151 mzelensky
 
25.12.19
10:05
(150) "функция создает новую сущность" - с эти не согласен. Например:


...

Если ВсеОбязательныеПоляЗаполнены() = Истина Тогда

Иначе
  Сообщить("Иди Заполняй как надо");
КонецЕсли;

...

Здесь "ВсеОбязательныеПоляЗаполнены()" это функция, которая никаких новых сущностей не создает, а просто выполняется проверка корректности заполнения данных. И в результате возвращается "истина\ложь".
152 Fish
 
25.12.19
10:07
(151) "Если ВсеОбязательныеПоляЗаполнены() = Истина Тогда" - Какой-то семёрочный код. Правильно писать так: "Если ВсеОбязательныеПоляЗаполнены() Тогда"
153 vi0
 
25.12.19
10:08
(151) возвращаемое значение - это и есть новая сущность, ты с ним и работаешь в блоке Если
154 tan76
 
25.12.19
10:23
*

Следует строго разграничивать proc(x) и func(x)
155 rsv
 
25.12.19
10:26
(152)  правильнее скорее убедиться что именно возвращается и не лишний раз проверить
явно
156 Fish
 
25.12.19
10:28
(155) Не правильнее. В данном случае всё, что не истина  - не подходит. Зачем лишняя операция сравнения?
157 ДенисЧ
 
25.12.19
10:31
(156) А если ВсеОбязательныеПоляЗаполнены() вернёт неопределено, как твоё условие сработает? ))
158 vi0
 
25.12.19
10:31
(155) если вернется не истина, то это явный баг в функции и сравнением с "Истина" этот баг будет скрываться
159 Fish
 
25.12.19
10:31
(157) Не поверишь, но точно так же :))
160 pechkin
 
25.12.19
10:31
(149) А текст исключения куда деваешь?
161 Fish
 
25.12.19
10:36
+(159) Точнее будет ошибка. Но не вижу смысла закладывать избыточную проверку на быдлокодерство.
162 pechkin
 
25.12.19
10:37
(161) это называется безопасный код.
код не должен падать... никогда
163 vi0
 
25.12.19
10:38
(162) этот код с багом не будет падать даже на этапе отладки
164 mzelensky
 
25.12.19
10:38
(161) А я вижу. И на практике много раз убеждался, что так правильней
165 Fish
 
25.12.19
10:38
(162) Имхо, это называется быдлокод. Если разработчик закладывает логику, что функция возвращает булево, то она должна возвращать именно булево, а не Неопределено или ссылку.
166 Fish
 
25.12.19
10:40
(164) Можно пример из практики? Только пример не связанный с быдлокодом, когда вместо ожидаемого значения типа булево, писатель функции возвращает непонятно что.
167 mzelensky
 
25.12.19
10:41
(160) Как правило туда же, в структуру возврата. Добавляю в "РезультатФункции" такие поля:

"ТекстОшибки" - текстовка из "ОписаниеОшибки()"
"КодОшибки"   - некое число, уникальное в рамках функции (1,2,3...). Это для простоты отладки и быстрого понимания где именно "пало". Т.к. Может быть много вложенных Попыток и разных сусловий приводящих к "РезультатФункции.ВыполненоУспешно = ложь"
168 pechkin
 
25.12.19
10:41
(166) значит концепция написания безопасного кода просто далека от тебя
169 rsv
 
25.12.19
10:43
(165) вот и проверяем на  истину ..но явно и перепроверяя движок
170 pechkin
 
25.12.19
10:44
(165) вот если бы в 1с была статическая типизация
171 Bigbro
 
25.12.19
10:44
из опыта:
вообще исторически так сложилось что проще и быстрее всего лупить линейный код, когда этот код ограничен одной страницей не имеет никакого смысла его разбиение на процедуры и функции.
когда кода становится много - есть смысл потратить немного времени разбить логически на процедуры и дальше продолжать в процедурах доработки.
затем когда уже в целом все работает, но появляются куски, которые могут и должны быть использованы в других местах решения - они выделяются в функции.
ну и дальше эволюционно должны уже возникать собственно классы.
все это имхо, у кого то может быть иначе.
172 Fish
 
25.12.19
10:45
(168) Да. Концепция бессмысленного пожирания лишних ресурсов далека от меня. Поэтому избыточные операции стараюсь не использовать.
173 mzelensky
 
25.12.19
10:45
(166) Вырывать пример из контекста я думаю смысла нет, будет не понятно. А постить сюда даже пару сотен строк кода тоже не хорошо, да и бестолку.

Я привел тебе конкретный пример, как это делаю Я. Делаю я это исходя из собственного опыта, практики и понимания, что код должен быть максимально защищен (чем больше защиты от дурака, тем лучше). Мой вариант более защищен и безопасен, чем твой.
174 Fish
 
25.12.19
10:46
(170) Чем мешает её отсутствие написать функцию, которая гарантированно возвратит булево? Неужели это искусство утеряно новым поколением программистов?
175 mzelensky
 
25.12.19
10:47
(172) Готов поспорит про "бессмысленного пожирания лишних ресурсов". Именно для данного прмиера.

Давай замеры производителности сделаем, :)
176 Fish
 
25.12.19
10:48
(173) Там, где производительность не важна, соглашусь, что можно писать так, что будет работать дольше, зато с кучей проверок "от дурака". Но истина, как обычно, посередине - нужен баланс, и ВСЕГДА вставлять проверки от дурака даже там, где они не нужны - имхо, лишнее.
177 rsv
 
25.12.19
10:49
(174) а вопрос не в том что она возвращает ..а в  том
Что несмотря на то что движок неявно может проверить результат

Лучша бааа ещё разок проверить через равно
178 Fish
 
25.12.19
10:49
(175) Ты хочешь сказать, что две последовательные операции сравнения будут работать так же, как и одна?
179 vi0
 
25.12.19
10:50
(169) проверка движка будет,как раз, если не сравнивать с булево, иначе в чем проверка заключается?
180 Fish
 
25.12.19
10:50
(177) А для функции ЗначениеЗаполнено() ты тоже пишешь
"Если ЗначениеЗаполнено(ХХХ) = Истина Тогда" ?

Вопрос и к mzelensky
181 Fish
 
25.12.19
10:53
(177) Что значит, неявно? Конструкция Если <Выражение> Тогда вполне себе явно проверяет результат на значение Истина.
Так зачем ещё раз ОТДЕЛЬНО проверять результат функции, если мы знаем, что результат должен быть типа булево?
182 rsv
 
25.12.19
10:54
(180) значение заполнено это функция  движка...
Но можно  и ее проверить .. но будем доверять
183 Fish
 
25.12.19
10:56
(182) Т.е. всё сводится к тому, что ты не доверяешь программисту, который написал данную функцию, заранее предполагая, что он быдлокодер и функция может вернуть не булево.
Ровно об этом я и говорил.
184 Fish
 
25.12.19
10:57
+(183) А если ты доверяешь разработчику функции (как в случае с функцией платформы), то доп. проверка уже излишняя.
185 Garykom
 
гуру
25.12.19
10:59
Хреновы спорщики так кто нить покажет хоть один пример (хотя бы в 1С) где требуется именно Процедура!
И нельзя обойтись функцией...
186 mzelensky
 
25.12.19
11:01
(180) Нет. Это встроенная функция. В нее "шаловливые ручонки" влезть не могут. Ее я не проверяю
187 Mort
 
25.12.19
11:02
(185) НоменклатураПриИзменении()  что вернешь?
188 Garykom
 
гуру
25.12.19
11:02
Как часто вы используете Goto в смысле Перейти ?

С ним я примеры такие знаю, обойтись без него можно (и миллионы 1Сников это доказывают при своей работе) но иногда с Перейти алгоритм-код получается удобнее и проще.
189 Fish
 
25.12.19
11:02
(186) Ну о чем я и говорил. Смотри (183) и (184).
190 Mort
 
25.12.19
11:03
(186) Т.е. возврат чего-то кроме булева это результат "шаловливых ручонок". Абсолютно согласен.
191 Garykom
 
гуру
25.12.19
11:03
(187) Еще раз. НИЧЕГО НЕ ВЕРНУ!

Вместо
Ном = НоменклатураПриИзменении();

Просто напишу
НоменклатураПриИзменении();

И все.
192 mzelensky
 
25.12.19
11:03
(183) Именно. Правило - "Доверяй, но проверяй".

Если бы ВСЮ систему от и до писал только Я, то таких проверок можно было бы избежать. Но т.к. обычно система пишется несколькими людьми, то я лучше проверю.

Тем более в плане производительности тут еще вопрос...что быстрее
193 Fish
 
25.12.19
11:05
(192) По мне, надо больше доверять людЯм :))
194 ДенисЧ
 
25.12.19
11:06
(191) Чем
функция, возвращающая void, отличается от процедуры?
кроме того, что процедура явно говорит, что от неё возвращаемого значения ждать не следует?
195 Mort
 
25.12.19
11:07
(191) Т.е. использовать её собираешься исключительно как процедуру, но при этом назвать процедурой не хотим.
196 ДенисЧ
 
25.12.19
11:07
197 Fish
 
25.12.19
11:07
+(193) Но т.к. я начинал программировать, когда каждый байт оперативы приходилось экономить, и от количества операций напрямую зависела скорость программы, то уже на автомате стараюсь не использовать избыточные операторы. Хотя в отдельных случаях соглашусь, это необходимо.
198 Конструктор1С
 
25.12.19
11:08
(149) зачем так услажнять? Пардон, но это не защитное программирование, а заSHITное программирование
199 Garykom
 
гуру
25.12.19
11:08
(194) А вот тут нужна строгая типизация и средства интерпретатора/компилятора должны проверять что функция ничего не возвращает а кто то хочет получить и код не запустится!

Короче введение раздельных Процедура и Функция это не смогли обойтись без типизации и сделали ее через одно место.
200 mzelensky
 
25.12.19
11:09
(193) После этих слов я начинаю НЕ доверЯть лЮдЯм еще больше!
201 Garykom
 
гуру
25.12.19
11:09
(195) Ты в курсе что у ненцев и прочих чукчей есть от 10 до 40 различных названий разного вида снега?

Ну там пухляк и т.д.
202 ДенисЧ
 
25.12.19
11:10
(199) В паскакале типизация строжей некуда. А всё равно разделили...
203 Йохохо
 
25.12.19
11:12
процедура это декоратор функции, или нет, всё плохо
204 Garykom
 
гуру
25.12.19
11:12
(202) В Обероне откуда вышел Паскаль процедур и функций нет вообще!
Там только модули.
205 mzelensky
 
25.12.19
11:13
(197) Это было актуально в эпоху нехватки мощности и когда программы писались узконаправленные и даже совершенно НЕ ориентированные на конечного пользоватля. Т.е. грубо говоря когда пользователь отдавал набор входящих данных программисту, программист писал программу по обработке этих данных (или вводил эти данные) и потом готовый результат отдавал в руки пользователю. В это случае любая ошибка отлавливалась и решалась самим программистом.

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

Именно поэтому системы должны быть максимально отказоустойчивы и выдерживать все мыслимые и немыслимые издевательства со стороны пользователей.
206 mzelensky
 
25.12.19
11:13
(205) Это я так, кратко изложил концепцию :)
207 Garykom
 
гуру
25.12.19
11:14
(204)+ Хотя ошибся, там есть процедуры но нет функций ))
208 Mort
 
25.12.19
11:15
Интересно если зайти на форум C++ и предложить отказаться от void в пользу какого нибудь класса с результатом работы функции, сс*ми тряпками сразу закидают или подождут?
209 Fish
 
25.12.19
11:15
(205) Ну тут не соглашусь: пользователь никак не может повлиять ТИП возвращаемого функцией значения. Тут речь именно о том, доверяешь ли ты писателю функции (включая себя) или нет.
210 Garykom
 
гуру
25.12.19
11:16
(208) В С++ "void" можно рассматривать как указание для функции 0 возвращаемых значений.
211 vi0
 
25.12.19
11:17
(192) > Правило - "Доверяй, но проверяй"
Для этого есть модульные тесты
212 Mort
 
25.12.19
11:17
(210) Что и есть процедура.
213 Garykom
 
гуру
25.12.19
11:18
Так будет пример для ЯП 1С где нельзя обойтись без Процедур?
214 Garykom
 
гуру
25.12.19
11:18
(212) Человек не выполняющий полезной работы перестает быть человеком?
А не возвращающий полученные деньги?
215 mzelensky
 
25.12.19
11:19
(211) Да ты ШО :)))

Год работы по системе BDD от "Сильвер Спун" меня многому научили, поверь! И это никак не повлияло на "Доверяй, но проверяй"
216 Mort
 
25.12.19
11:20
(214) Если хотите порассуждать о терминологии, то сообщите чем функция отличается от процедуры кроме букв в названиях.
217 Garykom
 
гуру
25.12.19
11:20
И да почему Функция возвращает только одно значение в большинстве старых ЯП?

Вот в новых (например Golang) Функция может возвращать несколько значений!
Это реально удобно не надо обертки с составными типами придумывать для возврата нескольких.
218 Garykom
 
гуру
25.12.19
11:21
(216) Процедур нет, это подвид Функций. Прцедура это урезанная Функция.
219 Mort
 
25.12.19
11:24
(218) Чем же урезанная? Давайте разберемся до конца!
220 Garykom
 
гуру
25.12.19
11:25
(219) Отняли возможность возвращать даже одно значение ))
221 Garykom
 
гуру
25.12.19
11:25
(220)+ Только через передачу параметров по ссылке можно из Процедуры что то вернуть.
222 Garykom
 
гуру
25.12.19
11:26
(221)+ Ну или через изменение глобальных переменных
223 Конструктор1С
 
25.12.19
11:26
(208) ходят слухи, в этих ихних C++ можно чуть ли не любое ключевое слово заменить с помощью #define и каких-то там трюков, тем самым как бы локально переделав C++ в собственный ЯП
224 Mort
 
25.12.19
11:27
(220) Отлично! Процедура это функция, которая не возвращает значение. Т.е. void P(t) это процедура.

Кстати само название "функция" как подрограммы пошло именно из математики, из выражений типа y=F(x);

Объединение функция и процедур произошло в языках позже для удобства синтаксиса.
225 Конструктор1С
 
25.12.19
11:28
(213) обработчики, не?
226 Xapac
 
25.12.19
11:30
(0)Вы балбес и зануда. Если вам не до чего докопаться в коде, а показать свою значимость нужно, то наверно оправдано, нор это не путь тру наставников.
227 Garykom
 
гуру
25.12.19
11:30
(225) Хороший пример, но это принудительное ограничение от разрабов платформы 1С.
228 vi0
 
25.12.19
11:30
(215) "Год работы по системе BDD от "Сильвер Спун" меня многому научили, поверь"
это не аргумент
229 Garykom
 
гуру
25.12.19
11:31
(227)+ Иногда я на это маты складываю, что приходится писать процедуру обертку (для уже имеющейся функции) и указывать ее имя в обработчике.
230 mzelensky
 
25.12.19
11:33
(228) Для кого как
231 Конструктор1С
 
25.12.19
11:39
Когда мне довелось массово переводить одну конфу с ОФ на УФ с работой под веб-клиент (безмодальность, асинхронные вызовы и все дела), я долго проклинал любителей злоупотребить функциями где ни попадя. Из-за их болезненной манеры всё подряд делать функциями, многие куски кода приходилось переписывать заново. В то время как нормальный код переделывался автоматически, или с небольшими переделками ручками
232 Mort
 
25.12.19
11:40
(227) Допустим платформенного ограничения нет и обработчики событий и оповещений могут возвращать значения. Какие Вы бы вернули значения и кому?
233 uno-group
 
25.12.19
12:36
Ну дык процедура на 28% длиннее функции. Соответственно кто вместо процедуры пишет функция, работает на 28% эффективнее перфекционистов.

Свой вариант
234 ДенисЧ
 
25.12.19
12:42
(233)
проCtrl-пробел
фунCtrl-пробел

ровно одинаковое количество
235 Fish
 
25.12.19
12:43
(234) А количество текста? Размер диска тоже не бесконечен :)
236 uno-group
 
25.12.19
13:04
(234) вы все еще набираете текст на клавиатуре? голосовой набор уже лет 15 как рулит.
237 Конструктор1С
 
25.12.19
13:20
(236) а как голосовой набор справляется с CamelCase и символами в коде?
238 Garykom
 
гуру
25.12.19
13:37
(237) Голос повышаешь и все
239 Лефмихалыч
 
25.12.19
17:56
(141) я засчитываю слив
240 dezss
 
30.12.19
11:01
(231) Вот про асинхронность не надо. Она просто сделана так, что без мата невозможно)))
241 fisher
 
30.12.19
14:24
(240) Она просто сделана. Точка.
Но когда цепочка асинхронных вызовов превышает "адын", то глаза вытекают :)
Я в таких случаях использую хитрый прием, когда за все отвечает один обработчик, в котором логика обработки разбита на этапы и расположена последовательно.
242 Конструктор1С
 
30.12.19
14:38
(240) не, ну когда код написан нормально, и всё на своих местах, то та асинхронность вообще не проблема. Рефакторинг - Нерекомендуемые синхронные вызовы - Преобразовать вызовы модуля. Может полностью переделать всё автоматом. Но если кто-то порукожопил в форме, то переделывание на асинхронные вызовы становится теми ещё шарадами
243 fisher
 
30.12.19
14:51
(242) Я асинхронные вызовы так и пишу до сих пор :) Пишу сначала синхронный (там уже все наизусть со старых времен), а потом мастером переделываю.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.