Можно ли временно переименовывать и блокировать встроенные функции?

Я хочу временно переименовать встроенный символ и использовать его с другим именем, в то время как заблокировать основное имя этого символа. Например, я хочу, чтобы следующий код печатал только "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 ответ

Решение

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

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

Другие вопросы по тегам