Обнаружение конфликтов DownValue/OwnValue

Иногда я сталкиваюсь со следующим сценарием: одна процедура использует глобальную функцию f[x] для выполнения некоторых вычислений, а другая процедура выполняет f=5, что превращает все последующие вызовы f[x] в 5[x].

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

Я не могу придумать законной причины смешивать OwnValues ​​и DownValues. Есть ли способ реализовать предупреждающее сообщение, когда происходит ситуация, подобная описанной выше?

В дополнение к приведенным ниже советам, контекст по умолчанию можно найти в OptionsInspector в разделе Параметры ячейки/Параметры оценки/CellContext.


person Yaroslav Bulatov    schedule 24.11.2010    source источник


Ответы (2)


Вы можете использовать Protect[f], чтобы избежать дальнейших назначений (любого рода), и Unprotect[f], чтобы разрешить их снова.

Вы также можете выполнить простой хакерский прием с повышающими значениями, чтобы предотвратить фактическое присвоение Set[f, ...] собственных значений f, но при этом разрешить присвоение понижающих значений без использования Protect/Unprotect:

In[76]:= ClearAll[f]

In[77]:= f /: Set[f, x_] := x

In[78]:= f = 7

Out[78]= 7

In[79]:= f

Out[79]= f

In[80]:= f[x_] := x + 1

In[81]:= f[1]

Out[81]= 2

Вышеупомянутое прозрачно блокирует использование Set на f. Выдача фактического сообщения также проста:

In[93]:= f::noov = "Blocked attempt to assign `1` as an OwnValue of f";

In[94]:= f /: Set[f, x_] := (Message[f::noov, x]; x)

In[95]:= f = 7

During evaluation of In[95]:= f::noov: Blocked attempt to assign 7 as
   an OwnValue of f

Out[95]= 7
person Michael Pilat    schedule 24.11.2010
comment
Что вы думаете о переопределении Set/SetDelayed для печати предупреждающего сообщения в случае конфликта DownValue/OwnValue? - person Yaroslav Bulatov; 24.11.2010
comment
Вероятно, возможно, но, вероятно, хрупко. Рассматривали ли вы вместо этого использование контекстов (Begin/End) или настройку контекстов на уровне ячейки/блокнота? - person Michael Pilat; 24.11.2010
comment
+1, я не думал об использовании таких значений. Умная. Кроме того, вы делаете хорошее замечание о контекстах уровня ячейки/блокнота; Я считаю их одним из самых полезных улучшений по сравнению с версией 5. - person rcollyer; 24.11.2010
comment
Я не знал о контекстах на уровне записной книжки, это где-то на страницах справки? - person Yaroslav Bulatov; 24.11.2010
comment
@Ярослав Булатов, в Mathematica 7 следуйте этому дереву меню: Оценка -> Контекст блокнота по умолчанию (внизу) -> Уникально для этого блокнота или каждой группы ячеек. Это работает, так как каждая группа ноутбуков/сот имеет, по сути, свой собственный Global. Так они друг другу не мешают. Контекст Cell Group удобен, когда у вас есть несколько способов что-то сделать, и вы хотите протестировать их все. - person rcollyer; 24.11.2010

Это не отвечает на первоначальный вопрос о создании предупреждающего сообщения, но отвечает на формальные символы удобны для использования в качестве глобальных символов. Они автоматически защищены и поэтому не могут быть случайно переопределены. Вы вводите формальный символ с помощью клавиш <ESC>$f</ESC>, где f может быть любой буквой. Недостатком является то, что для ввода символа требуется четыре нажатия клавиши вместо одного.

person WReach    schedule 12.12.2010
comment
+1 за полезный лакомый кусочек. Можно ли программно сгенерировать (скажем, внутри пакета) формальные символы из двойных или греческих букв? Если нет, я полагаю, что примеры MakeBoxes в документации по формальным символам допускают замену (символа и/или цвета). Это может быть действительно полезным дизайнерским трюком. :) - person telefunkenvf14; 13.04.2011
comment
@ telefunkenvf14 Если вы имеете в виду характерный внешний вид формальных символов (с точками вверху и внизу), я не знаю, как создать другие такие символы. Насколько я понимаю, буквы с точками — это символы специального шрифта. Вероятно, можно приблизиться, используя Underoverscript и Symbolize, но результаты могут быть хлопотными при вводе с клавиатуры. Другие характеристики формальных символов, то есть отсутствие встроенных определений и защита с помощью Protect, легко согласуются с любым другим символом. - person WReach; 13.04.2011