Имя: Пароль:
1C
 
Пятничная загадка
0 Mort
 
21.10.11
12:50
Загадка, конечно громко сказано. Но например, в книжках "Сложные задачи для С++" есть ряд малоприменимых, но интересных задач, например, сколько раз подряд можно в С++ написать символы +,> и т.д. Система 1С не богата на подобные вопросы, но нижеописанный случай показался интересным для разбора.

Наткнулся на баг в программке который вызван тем, что оператор "=" изменил _правый_ аргумент.
Собственно загадка для новичка в том как это случилось, а для профа вспомнить любые такие возможные случаи.
1 БалбесВ1с
 
21.10.11
12:52
Все загадки в 1С решаются очисткой кэша.
2 aleks-id
 
21.10.11
12:52
В=А=В
3 Wobland
 
21.10.11
12:53
(2) правый операнд: А=Б
4 Axel2009
 
21.10.11
12:56
какой оператор?
5 Mort
 
21.10.11
13:04
Никакого косяка в кэше нет. Простой правкой кода изменение убирается. Объясню точнее:

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

Выражение1 = Выражение2;

Выражение2 изменяется.
Под "изменяется" имеется ввиду любое изменение в свойствах объекта (ну то что выражение2 не примитивное значение, думаю сразу ясно).
6 Axel2009
 
21.10.11
13:10
эх, не проф я получается, раз такой фигни не знаю..
давай поведай, а?
7 marty0701
 
21.10.11
13:11
(5) напиши по человечески эти 2 выражения сюда, в которых обнаружен "баг".
8 marty0701
 
21.10.11
13:11
(5) И еще напиши левый операнд не изменился типо, а правый только изменился?
9 Wobland
 
21.10.11
13:12
(5) б= НЕ б; б=-б; вроде подходит
10 marty0701
 
21.10.11
13:13
(9)Там целое выражение слева и справа.
11 Mort
 
21.10.11
13:14
(6) Ну может я погорячился, когда сказал, что задача для новичков. Когда узнаешь оно потом всегда легко кажется. А какие-нибудь предположения.

(7) Баг не в этом, это судя по всему нормальное поведение платформы, просто из-за того что не учли эту особенность, функциональность не соответствовала в полной мере заданной.

(8) Левый, конечно, изменился.
12 Mort
 
21.10.11
13:16
Подсказка: никаких операций кроме разыменования (. и []) ни в левом ни в правом выражениях нет.
13 marty0701
 
21.10.11
13:21
(12)Значение в памяти изменилось?
14 Lama12
 
21.10.11
13:21
В правой часте равенства работа ведется с объектом или с его формой. Естествнно отрабатывает код в модуле (контекстный) и еще часть типа при создании и т.д. Аналогично и для формы.
15 Lama12
 
21.10.11
13:22
(14) Что ни будь типа этого а = Спр.Ссылка.ПолучитьОбъект();
16 Lama12
 
21.10.11
13:23
Но такие вещи должны проходить только при "не корректном" коде в объектах.
17 Lama12
 
21.10.11
13:25
Дайте ответ!
ИМХО. Задача сводится к коду который выполняется при инициализации объекта.
18 Mort
 
21.10.11
13:29
(13) Да.
19 Ненавижу 1С
 
гуру
21.10.11
13:31
А=Б.Тест();

функция Тест вполне могла изменить состояние объекта Б
20 marty0701
 
21.10.11
13:32
:D
21 Lama12
 
21.10.11
13:33
(19) Вот и я про тоже ;)
22 Ахиллес
 
21.10.11
13:36
Давайте голосовать:
1. Mort нашел косяк платформы.
2. Mort нубас и апазорился, нет никакой ошибки.

Я голосую зп п.2
23 Ахиллес
 
21.10.11
13:38
Всё что выше написали это нормалное поведение платформы и багом уж никак не является.
24 Mort
 
21.10.11
13:38
(19) Хороший вариант, но не вполне подходит под условие задачи - должно изменяться именно выражение.
25 Mort
 
21.10.11
13:39
(22) Апозоришься ты, когда я очевидное решение выложу.
26 Mort
 
21.10.11
13:39
+(24) А не его часть.
27 Mort
 
21.10.11
13:40
Ладно, я буду рассуждать по шагам, кто первый допрет того и тапки.
28 Ахиллес
 
21.10.11
13:41
Я не могу апазорится. Я пока, что не написал никакого неверного кода тут. Хотя не правым конечно могу оказаться.
29 marty0701
 
21.10.11
13:42
(27)Дык что написать то нужно, есть у вас процедура\функция вы в нее передали значение по ссылке, оно изменилось, получили другое выражение. все. или нет?
Не могу найти ошибку в коде - что - то типа того?
30 Mort
 
21.10.11
13:43
(29) Нет никаких вызовов процедур, в (12) уже писал.
31 Mort
 
21.10.11
13:43
Итак, размышляем:


Шаг 1. Выражение2 (а это некий объект) изменяется попадая в выражение1 т.е. идет присвоение не копии значения, а некоторой ссылки на значение. Например коллекции.
32 Сниф
 
21.10.11
13:47
Не вьеду в чем загадка.

Результат = Выборка.Следующий();

В чем загвоздка-то?
33 Mort
 
21.10.11
13:47
Кто дальше?
34 Mort
 
21.10.11
13:48
(32) смотри (12)(19)(24)
35 marty0701
 
21.10.11
13:48
(32)Я вот тоже смысла не очень догоняю, ну перну в лужу, неявный сдвиг.
36 Ахиллес
 
21.10.11
13:49
(32) Загадка в том, что ТС считает ситуацию БАГОМ. То есто платформа делает нечто, что от неё не ожидают.
37 Error pro
 
21.10.11
13:50
(32) выражение1 = выражение2[индекс];  ?
38 Axel2009
 
21.10.11
13:50
ладно, купил попкорн, посижу подожду, когда у ТС иссякнет ЧСВ =)
39 Mort
 
21.10.11
13:50
(36) Читаем (11). Платформа делает все правильно, баг вообще ни причем, просто автор (я) в некоторый момент не учел такого поведения.
40 Ненавижу 1С
 
гуру
21.10.11
13:50
А.Тест().Б=В;
вполне себе Тест() мог изменить В
41 Ахиллес
 
21.10.11
13:52
(39) Прочитай собственный (0) пост: >Наткнулся на баг в программке...
Если ты чего то не знал или не учёл, нафига тут было ветку заводить?
42 marty0701
 
21.10.11
13:52
Не понял, надо написать как именно у тебя сейчас это случилось? Т.е. надо угадать твои выражение1 и выражение2? Или дать просто ответ почему это случилось?
43 Axel2009
 
21.10.11
13:53
это типа
СЗ = новый списокзначений;
СЗ.добавить(1);
Эл = СЗ[0];
СЗ = Эл.Значение;
?
44 Сниф
 
21.10.11
13:54
Морт, выкладывай свой косяк.
45 Mort
 
21.10.11
13:55
(40) Это вариации на тему (19). Да такой вариант в силу кривоты выражения в (0) проходит. Думаю можно засчитать.

А теперь задача сделать без использования вызовов процедур.

(42) Да, нужно сказать что должно быть в выражении1 и выражении2, чтобы так получилось.
46 Mort
 
21.10.11
13:58
Размышляем дальше:

Шаг1: (31)
Шаг2: Если значение по ссылке изменилось значит присваиваемое значение чем-то не понравилось. Начинает попахивать типами...
47 Mort
 
21.10.11
13:59
Шаг3. Т.е. Выражению1 не понравились типы элементов присваиваемой коллекции.

Пошел обедать.
48 Axel2009
 
21.10.11
14:00
походу высокое ЧСВ у ТС
49 Ахиллес
 
21.10.11
14:03
Напортачил с переменными наверное, по типу как в (43) и сразу "БАГ ПРОГРАММЫ" :-)
Морт, смирись уже с тем, что присваивание меняет всегда левый аргумент. А если ты не учёл, что левый и правый аргументы у тебя суть одно и тоже, то ты сам себе злобный буратино и 1С тут ни при чём.
50 Eugene_life
 
21.10.11
14:04
Тема не дотянет до 100 постов, к чему стремится ТС :)
51 Lama12
 
21.10.11
14:14
Тогда так.
А = 1;
Б = "Привет";
В = Б+А;
В памяти А преобразуется к "1".
Но само значение переменной А не изменится.
52 Mort
 
21.10.11
14:15
(48) Заладил ЧСВ, ЧСВ. Да скромность это мой главный недостаток.
(49) Я не жалуюсь и смирятся мне нечему. Если решение загадки неинтересно - дуй в пятничную.
(50) Всю жизнь мечтал о ветке в 100 постов.
53 acsent
 
21.10.11
14:17
(0) Это не баг, а твое непонимание передчи параметров по ссылке
54 PR
 
21.10.11
14:18
(52) Твоя загадка с большой натяжкой относится к 1С и v8.
Твоя загадка совершенно не является математикой и даже алгоритмом.
Так что постепенное вымучивание ответа напоминает мне, как в детстве нам пацанам подвыпивший мужик гордо в течении минуты хотел показать фокус, крутил карты в руках, что-то соображал... По истечении минуты отдал карты и мы разочарованные оставили его в гордом одиночестве и пошли играть в карты :))
55 Mort
 
21.10.11
14:21
Шаги никто не читает. Ну и ладно, продолжу.

Шаг 4. А где в 1С есть коллекции, которые приводят типы элементов присваиваемого значения?

Собсно ответ уже практически дан.

(53) А ветку почитать? Я про баг пять раз уже сказал что он к загадке не имеет отношения.
(54) Я даю наводки.

Ладно, покурю, выложу полностью и картинку нарисую. Отмазки, что отстой потому что элементарно можно не выкладывать. Нужно было не пытаться ошибку у меня искать, а ответ.
56 aleks-id
 
21.10.11
14:26
щас он нам замутит с отбором строк тз...
57 Megas
 
21.10.11
14:27
Перем1 = Перем2;

Если перем1 - это строка тз
перем2 - массив строк тз

чёто типо того
58 Ахиллес
 
21.10.11
14:29
(51) Чего это вдруг? Как было числом так и останется. В чем легко убедится:
А = 1;
Б = "Привет";
В = Б+А;
Сообщить(ТипЗнч(А));
59 Mort
 
21.10.11
14:29
(56) Наконец-то.

Ответ:

СправочникСписок.Отбор.Владелец.Значение = СЗ;

Все элементы СЗ будут приведены к типу владельца справочника. Всё.

А кого интересует баг, там было немного посложнее. Типы элементов соответствовали типу элемента отбору, но расширялся перечень типов для редактирования списка в поле ввода.
60 PR
 
21.10.11
14:33
(59) Мда. Я не ошибся :))
61 Mort
 
21.10.11
14:35
(60) Ты про секцию математика и алгоритмы? Это не я назначил. А то что "с большой натяжкой относится к 1С и v8." это ты и сейчас утверждаешь?
62 PR
 
21.10.11
14:36
(61) Я про то, что интересного в сабже нольцелыхнольдесятых. IMHO ессно :))
63 Mort
 
21.10.11
14:36
(62) А чо решение не вложил если всё просто?
64 PR
 
21.10.11
14:41
(63) Где в (62) ты прочитал "просто"? :))
65 Ненавижу 1С
 
гуру
21.10.11
14:42
ну вообще я считаю, что это именно БАГ ПОВЕДЕНИЯ предопределенных объектов
66 Fragster
 
гуру
21.10.11
14:43
в натуре бага есть
67 Mort
 
21.10.11
14:46
Это не баг, а фича.
68 smaharbA
 
21.10.11
14:51
писец, всегда это называлось неявной типизацией
69 smaharbA
 
21.10.11
14:51
и это существует с рождения абака
70 Alexandr Puzakov
 
21.10.11
14:56
Пилять! Вот это бесполезное прожигание времени вы тут устроили х-|
71 Ахиллес
 
21.10.11
14:56
Пятница. Кули.
72 Fragster
 
гуру
21.10.11
14:57
(67) почему оно не копию делает, а ссылку на значение?
73 Дык ё
 
21.10.11
15:00
(67) чтобы стать фичей, этот баг должен быть описан в документации. номер страницы не напомнишь?
74 Fragster
 
гуру
21.10.11
15:01
Список = Новый СписокЗначений;
   
   ЭлементОтбора = ТабличноеПоле1.Отбор.Найти("Владелец");
   Сообщить(ЭлементОтбора);
   ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
   ЭлементОтбора.Значение = Список;
   ЭлементОтбора.Значение.Добавить(11);
   
   Сообщить(Список.Количество());
75 Fragster
 
гуру
21.10.11
15:02
походу в Значение передается ссылка, но в сеттере установлена обработка значения с приведением типа
76 Ненавижу 1С
 
гуру
21.10.11
15:04
(68)(69) да ты че? чтоб при этом источник менялся?
77 Mort
 
21.10.11
15:04
(73) Если так рассуждать, то половина СКД сплошной баг.
78 Ненавижу 1С
 
гуру
21.10.11
15:07
(77) ну есть хотя бы общепринятые принципы, если они нарушаются, то это как минимум не есть гут
79 Mort
 
21.10.11
15:09
(78) А хорошего решения для такого случая не придумаешь. Копировать всю коллекцию тоже не замечательное решение, оставлять черти что в списке отбора тоже нехорошо.
80 Ненавижу 1С
 
гуру
21.10.11
15:12
(79) а я бы вообще не приводил, ибо нех
с какого он автоматом их приводит то?
81 Ненавижу 1С
 
гуру
21.10.11
15:12
надо было использовать идеологию "ленивых вычислений", но 1с же такой 1с
82 Mort
 
21.10.11
15:14
(80) Тогда бы системе пришлось удалять шлак каждый раз во время отбора.
83 Ненавижу 1С
 
гуру
21.10.11
15:15
(82) пережили бы ))
84 Mort
 
21.10.11
15:15
Кстати в списках выбора, возможно, таже херня.
85 Ненавижу 1С
 
гуру
21.10.11
15:16
баг в 1с начинается уже с того, что значения аргументов передаются по умолчанию по ссылке, а не по значению
причем хотя и по ссылке, но можно при этом передать и не l-value значение в аргумент
86 Mort
 
21.10.11
15:18
(85) Ты представляешь, какое количество (и без того не малое) г0внокода бы полилось, если бы сделали по-умолчанию по значению?
87 Ненавижу 1С
 
гуру
21.10.11
15:21
(86) а его и щас не мало, тем более не велика потеря, ибо щас поведение возврата аргумента зависит от контекста вызова ))

Процедура Тест(А)
А=А+1;
КонецПроцедуры;

Тест(ДокументОбъект.Х); //меняет значение
Тест(ДокументСсылка.Х); //не меняет значение

и к тому же все составные объекты (коллекции и оное) все равно есть суть ссылки
88 Mort
 
21.10.11
15:23
(87) Оба не меняют. Плохой пример.
89 Ненавижу 1С
 
гуру
21.10.11
15:29
(88) врешь, я проверил даже ))
90 sda553
 
21.10.11
15:33
Говорят вот эта программа выводила на экран что то осмысленное, но проверить сейчас не на чем

#include <stdio.h>
main(t,_,a)
char *a;
{
return!0<t?t<3?main(

 -79,-13,a+main(
   -87,1-_,main(
     -86,0,a+1
     )+a
   )
 ):1,t<_?main(
 t+1,_,a
 ):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t,
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#\
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \
}'+}##(!!/")
:t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)
 :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);
}
91 Mort
 
21.10.11
15:39
(89) Да, вру, перепутал с другим случаем.
Кста, тут по ссылке ошибка вылезет.
92 Ненавижу 1С
 
гуру
21.10.11
15:41
(91) согласен
93 Mort
 
21.10.11
15:43
(90) Похоже на задачу вывода текста программы.
94 Ненавижу 1С
 
гуру
21.10.11
15:45
+(92) но опять же, значит есть попытка вернуть значение, однако стоит написать

Тест(ДокументСсылка.Х+0);

и такая попытка напрочь утрачивается, вопрос, а почему?
95 Ненавижу 1С
 
гуру
21.10.11
15:48
кстати в копилку багов "при игре на грани фола", только что обнаружил, если ТЧ (например, документа) не содержит реквизитов, то выдается ошибка на код:

Стр = Объект.ТЧ.Добавить();
Сообщить(Стр.НомерСтроки); //нет такого реквизита!

добавляем реквизит - ошибка пропадает
96 sda553
 
21.10.11
16:25
Отгадайте пятничную загадку пожалуйста, а то она мне всю пятницу портит, собака
http://s017.radikal.ru/i437/1110/6f/a1bfd7d538e8.jpg
ексель - какого фига получился бесконечный цикл?

Пояснение i должен был пройти цикл с 4 по 5, а он уже вон 21 и не собирается останавливаться(все переменные открыл в watches)
97 Ненавижу 1С
 
гуру
21.10.11
16:27
(96) а в средней строке точно ничего интересного нет?
98 sda553
 
21.10.11
16:36
(97) Абсолютно! все вычистил
99 Mort
 
21.10.11
16:38
А Type Variant/Long basik для всех переменных пишет?
100 Mort
 
21.10.11
16:38
(50) Салют!
101 sda553
 
21.10.11
16:40
(99) Вопрос непонятен
102 Mort
 
21.10.11
16:44
(101) Ну в окне отладки.
103 sda553
 
21.10.11
16:46
(102) Ну да, то что написано на скрине, так прямо и пишет
104 Axel2009
 
21.10.11
16:47
а если один вложенный цикл убрать?
105 Mort
 
21.10.11
16:49
Отладка слетела (с) 1С.
Кэш почисти. :)
106 sda553
 
21.10.11
16:51
(104) При убирании вложенного цикла этот цикл по i становится конечным и выходит когда надо. И в чем отгадка?
107 sda553
 
21.10.11
16:53
Замена буквы i на p лечит проблему, но загадка все равно загадочна
Ошибка? Это не ошибка, это системная функция.