Можно ли временно переименовывать и блокировать встроенные функции? - PullRequest
5 голосов
/ 27 апреля 2011

Я хочу временно переименовать встроенный символ и использовать его с другим именем, в то же время блокируя основное имя этого символа.Например, я хочу, чтобы следующий код печатал только «2», но не «1» и «3»:

Block[{print = Print, Print}, Print[1]; print[2]; Print[3];]

В действительности вышеприведенный код ничего не печатает.

Можно ли заставить print работать внутри такого кода, пока полностью блокируется символ Print?

Решения типа

With[{Print = f, print = Print}, Print[1]; print[2]; Print[3];] 

не подходят, поскольку PrintНа самом деле не блокируется внутри такого кода.

Вопрос возник, когда думает о способе отключения трассировки Message внутренних компонентов.

1 Ответ

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

Это не очень чисто, но я считаю, что это исправно.

Internal`InheritedBlock[{Print},
  Unprotect[Print];
  Print[x__] := Null /; ! TrueQ[$prn];
  print[x__] := Block[{$prn = True}, Print[x]];
  Print[1]; print[2]; Print[3];
]

Если недопустимо заменять функцию на Null в ответ, вам может понадобиться что-то вроде:

func[x__] := Hold[func[x]] /; ! TrueQ[$prn];

После блока ReleaseHold.

Или:

func[x__] := zz[x] /; ! TrueQ[$prn];

и затем следуйте блоку с: /. zz -> func

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