Безопасно ли создавать модуль внутри другого, используя те же местные символы? - PullRequest
4 голосов
/ 22 декабря 2011

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

Вот глупый пример с одним модулем и вспомогательным модулем внутри него к чему-то

foo[x_] := Module[{r},

  r = Module[{y, sol},
    sol = First@Solve[y^2 + 3 y + 2 == 0];
    y /. sol
    ];

  x^r

  ]

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

foo[x_] := Module[{r, y=0},

  r = Module[{y, sol},
    sol = First@Solve[y^2 + 3 y + 2 == 0];
    y /. sol
    ];

  x^r

  ]

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

enter image description here

(M нужно использовать лучшие цвета, трудно различить многие цвета, все оттенки красного).

enter image description here

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

Значение локальной переменной родительского модуля 'y' в этом примере не было переписано при вызове внутреннего модуля 'r', что хорошо.

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

Конечно, я всегда мог написать:

foo[x_] := Module[{r, y, sol},

  sol = First@Solve[y^2 + 3 y + 2 == 0];
  r = y /. sol;

  x^r

  ]

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

Мой вопрос: просто хотите уточнить у экспертов здесь, безопасно ли для меня использовать вышеизложенное, даже несмотря на то, что М дает мне это предупреждение о красной окраске? и если есть что-то, что мне нужно беспокоиться об этом

спасибо,

Ответы [ 2 ]

8 голосов
/ 22 декабря 2011

Да, безопасно использовать ту же самую переменную во вложенном Modules , если вы не потеряете их .Mathematica рассматривает каждую переменную, определенную в Module, как локальную для этого модуля.Локальные переменные Temporary и пронумерованы как variable$ModuleNumber.Вы можете проверить это на следующем примере:

Module[{x = 1},
 Print[HoldForm@x, " = ", x]
  Module[{x = 2},
   Print[HoldForm@x, " = ", x]
    Module[{x = 3},
     Print[HoldForm@x, " = ", x]
    ];
   Print[HoldForm@x, " = ", x]
  ];
 Print[HoldForm@x, " = ", x]
]

(*Output
x$4576 = 1
x$4577 = 2
x$4578 = 3
x$4577 = 2
x$4576 = 1
*)
2 голосов
/ 22 декабря 2011

Насколько мне известно, это небольшая проблема с обнаружением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...