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