5

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.

Community
  • 1
  • 1
Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93
  • 1
    Alexey, you do find the difficult questions. – Mr.Wizard Apr 27 '11 at 07:40
  • And what if you use Hold instead of f? Does that not block Print (but not print) correctly? – István Zachar Apr 27 '11 at 07:43
  • @István, now it seems clear what you meant. The problem is that `With` only replaces explicit instances of a symbol, while `Block` temporarily replaces the symbol for all calls within the Block, even those that are hidden. – Mr.Wizard Apr 27 '11 at 08:53
  • 1
    You are not the only one who would like this functionality. In my fourth post in this thread, http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/a39d99bc1470bb3c, I described a hypothetical function `Unblock` which would do exactly what you want. Ideally, it would work in concert with `Block`, allowing many levels of nesting of blocking and un-blocking. Unfortunately, AFAIK, there is no built-in `Unblock` - like function. I'd be happy to learn that I am wrong. – Leonid Shifrin Apr 27 '11 at 19:08

1 Answers1

6

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

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125