SaveDefinitions считается опасным

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

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

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

enter image description here

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

f[x_] := x^2

Manipulate[
 Plot[n f[x], {x, -3, 3}],
 {n, 1, 4},
 SaveDefinitions -> True
 ]

Все работает отлично, Manipulate действительно сияет, сегодня хороший день.

enter image description here

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

enter image description here

Да, все еще проверяется. Хорошо. Но теперь вам приходит в голову, что лучшей волнистой функцией была бы синусоида, поэтому вы меняете определение, выполняете и, будучи параноиком, проверьте:

enter image description here

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

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

enter image description here

Теперь вы прокручиваете вниз до поля «Манипулировать» (не нужно повторновыполнить благодаря SaveDefinitions ), поиграйте немного с ползунком. И прокрутите назад.

enter image description here

Будучи параноиком, вы еще раз проверьте определение f:

enter image description here

И вот, кто-то изменил определение за вашей спиной! И ничего не было выполнено между вашей первой и второй проверкой информации (?) В соответствии с числами In [] ( In [1] : def of f, In [2] первый?, В [3] второй?).

Что произошло? Ну, конечно, это Manipulate . FullForm раскрывает его внутреннюю структуру:

Manipulate[Plot[n*f[x],{x, -3, 3}],{{n, 2.44}, 1, 4},Initialization:>{f[x_] := x^2}]

Вот и виноват. Часть инициализации блока снова определяет f, но это старая версия, потому что мы не переоценивали Manipulate после изменения его определения. Как только поле манипулирования появляется на экране, оно оценивается, и вы получаете обратно свое старое определение. Глобально!

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

Ясно, что мне хочется сказать, что это нежелательное поведение. Теперь, что касается обязательного вопроса: , что мы можем сделать, чтобы предотвратить такое скрытое поведение Manipulate , кроме повторного выполнения каждого Manipulate в вашей записной книжке. когда вы измените определение, которое могло бы использоваться ими?

20
задан Sjoerd C. de Vries 5 July 2011 в 08:13
поделиться