Uncaught Throw генерируется JLink или UseFrontEnd - PullRequest
5 голосов
/ 02 октября 2011

В этом примере подпрограмма генерирует два предупреждающих сообщения Throw :: nocatch в окне ядра.Можно ли их как-то обработать?

Пример состоит из этого кода в файле "test.m", созданного в C: \ Temp:

Needs["JLink`"];
$FrontEndLaunchCommand = "Mathematica.exe";
UseFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];

Затем эти команды вставляются и выполняются вКомандная строка Windows:

PATH = C:\Program Files\Wolfram Research\Mathematica\8.0\;%PATH%
start MathKernel -noprompt -initfile "C:\Temp\test.m"

enter image description here

Добавление

Причина использования UseFrontEnd в отличие от UsingFrontEnd заключается в том, что интерактивный внешний интерфейсможет потребоваться сохранить выходные данные и сообщения из записных книжек, которые обычно запускаются в интерактивном режиме.Например, с C: \ Temp \ test.m, измененным следующим образом:

Needs["JLink`"];
$FrontEndLaunchCommand="Mathematica.exe";
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
SelectionMove[nb, Next, Cell];
SelectionEvaluate[nb];
];
Pause[10];
CloseFrontEnd[];

и записной книжкой C: \ Temp \ run.nb, созданной с одной ячейкой, содержащей:

x1 = 0; While[x1 < 1000000,
 If[Mod[x1, 100000] == 0,
  Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]];

этот код, запущенный из командной строки Windows, будет работать в интерактивном режиме и сохранять свои выходные данные.Этого невозможно достичь с помощью скрипта UsingFrontEnd или MathKernel "C: \ Temp \ test.m".

1 Ответ

5 голосов
/ 08 ноября 2011

Во время инициализации код ядра находится в режиме, который предотвращает прерывания.

Throw / Catch реализован с помощью Abort, поэтому они не работают во время инициализации.

Простой пример того, чтопоказывает, что проблема заключается в том, чтобы поместить это в файл test.m:

Catch[Throw[test]];

Аналогично, такие функции, как TimeConstrained, MemoryConstrained, Break, семейство Trace, Abort и те, которые зависят от него (например, определенные пакеты данных)будут проблемы, подобные этой, во время инициализации.

Возможное решение вашей проблемы может заключаться в рассмотрении опции -script:

math.exe -script test.m

Также обратите внимание, что в версии 8 есть документированная функцияназывается UsingFrontEnd, который делает то же, что и UseFrontEnd, но настраивается автоматически, поэтому:

Needs["JLink`"];
UsingFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];

должно быть всем, что вам нужно в файле test.m.

См. также: Mathematica Scripts

Приложение

Одним из возможных решений использования -script и UsingFrontEnd является использование сценария run.mт включен ниже.Это требует настройки «Тестового» ядра в настройках ядра (в основном это клон «Локальных» настроек ядра).

Сценарий включает две служебные функции, NotebookEvaluatingQ и NotebookPauseForEvaluation, которые помогают сценарию дождаться завершения оценки записной книжки клиента перед его сохранением.Преимущество этого подхода заключается в том, что весь управляющий код оценки находится в сценарии run.m, поэтому в записной книжке клиента не обязательно указывать оператор NotebookSave [EvaluationNotebook []] в конце.

NotebookPauseForEvaluation[nb_] := Module[{},While[NotebookEvaluatingQ[nb],Pause[.25]]]

NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or@@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]

UsingFrontEnd[
nb = NotebookOpen["c:\\users\\arnoudb\\run.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb];
]

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

Кстати, я попробовал еще один подход:используя это:

UsingFrontEnd[ NotebookEvaluate[ "c:\\users\\arnoudb\\run.nb", InsertResults->True ] ]

Но это переводит сеанс терминала ядра в диалоговый режим, что мне кажется ошибкой (я проверю это и сообщу, если это допустимая проблема).

...