Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to rename and block built-in functions temporarily?

I wish to temporarily rename a built-in symbol and use it with different name while block the main name of this symbol. For example, I wish the following code to print only "2" but not "1" and "3":

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

In really the above code prints nothing.

Is it possible to make print working inside such code while completely block symbol Print?

Solutions like

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

are not suitable since Print is not really blocked inside such code.

The question appeared while thinking on a way to disable tracing of Message internals.

like image 767
Alexey Popkov Avatar asked Apr 27 '11 06:04

Alexey Popkov


1 Answers

This is not very clean, but I believe it is serviceable.

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

If it is not acceptable to have the function replaced with Null in the return, you may need to use something like:

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

Followed by a ReleaseHold after the Block.

Or:

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

and then follow the Block with: /. zz -> func

like image 181
Mr.Wizard Avatar answered Oct 13 '22 20:10

Mr.Wizard