Как прервать оценку последовательности входов? - PullRequest
4 голосов
/ 11 апреля 2011

По умолчанию нажатие Alt + . или вызов Abort[] в пределах оценки вызывает прерывание текущего оцениваемого ввода.Но при работе во FrontEnd мы обычно отправляем ядру последовательность входных данных.Например, если мы введем следующие три выражения в отдельных строках в одну Cell, а затем нажмем Shift + Введите , мы получим бесконечную оценку:

f := CheckAbort[Pause[.1], Abort[]]
While[True, f]
While[True, f]
While[True, f]

Чтобы остановить эту бесконечную оценку, мы должны нажать Alt + . три раза.

Как определить функцию f в приведенном выше примере таким образом, чтобынажатие Alt + . один раз прервет оценку полной последовательности входных данных без выхода из ядра ?

EDIT

Я думаю, что если FrontEnd создает входную очередь для MathKernel, он, вероятно, также может отменить эту очередь.

Ответы [ 3 ]

6 голосов
/ 11 апреля 2011

Предложение Саши просто использовать четыре ячейки является верным, потому что это в основном то, что делает FrontEnd в любом случае, отправляя несколько отдельных оценок в Ядро.Если вы настаиваете на использовании одной ячейки, оберните ее в скобках (CompoundExpression), в результате чего эти четыре строки будут рассматриваться как одна оценка (обратите внимание на необходимость ; тоже):

(
   f := CheckAbort[Pause[.1], Abort[]];
   While[True, f];
   While[True, f];
   While[True, f]
)

Затемодна отмена отменяет оценку в целом.

1 голос
/ 13 апреля 2011

Алексей, пожалуйста, попробуйте эту версию своего кода и скажите мне, если / когда он потерпит неудачу:

AbortAllPendingInputs :=
  AbortProtect[
    $new$PreRead = True;
    $TimeOfAbort = SessionTime[];
    last$PreRead = $PreRead;
    $PreRead = 
      If[
         TrueQ[SessionTime[] - $TimeOfAbort < 1], 
         "",
         $new$PreRead = False; $PreRead = last$PreRead; $PreRead[#]
        ] &;
  ] /; ! TrueQ[$new$PreRead]
1 голос
/ 12 апреля 2011

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

In[1]:= $new$PreRead = False;
AbortAllPendingInputs := 
  AbortProtect[If[! $new$PreRead, $new$PreRead = True;
    $TimeOfAbort = SessionTime[];
    last$PreRead = ToString[Definition[$PreRead], InputForm];
    ClearAll[$PreRead];
    $PreRead := If[TrueQ[SessionTime[] - $TimeOfAbort < 1], "",
       $new$PreRead = False;
       ClearAll[$PreRead];
       If[last$PreRead === "Null", #, 
        ToExpression[last$PreRead]; $PreRead@#]
       ] &;]];

In[3]:= f := CheckAbort[Pause[10], AbortAllPendingInputs; Abort[]]

In[4]:= While[True, f]
While[True, f]
While[True, f]

Out[4]= $Aborted

Но я все еще ищу более элегантное решение. Я думаю, что если FrontEnd создает очередь ввода для MathKernel, он, вероятно, также может отменить эту очередь.

...