Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Block Symbols without evaluating them?

Suppose I have a list of names of Symbols:

f1 := Print["f1 is evaluated!"];
list = {"f1", "f2"};

The obvious way to Block these Symbols leads to evaluation of them:

In[19]:= With[{list=Symbol/@list},Block[list,f1//ToString]]
During evaluation of In[19]:= f1 is evaluated!
During evaluation of In[19]:= f1 is evaluated!
Out[19]= Null

But without evaluation we could Block them without any problem:

In[20]:= Block[{f1, f2}, f1 // ToString]
Out[20]= "f1"

Is it possible to inject this list into the Block scope without evaluating the Symbols?

like image 956
Alexey Popkov Avatar asked Jun 04 '11 04:06

Alexey Popkov


1 Answers

Here is yet another technique to do this:

SetAttributes[blockAlt,HoldRest];
blockAlt[s : {__String}, body_] :=
   Replace[Join @@ ToHeldExpression[s], Hold[x__] :> Block[{x}, body]]

We save here on pure functions, due to the disruptive nature of rules (they don't respect other scoping constructs, including themselves)

EDIT

Yet another alternative (even shorter):

SetAttributes[blockAlt1, HoldRest];
blockAlt1[s : {__String}, body_] :=
   Block @@ Append[ToHeldExpression@ToString[s], Unevaluated[body]] 
like image 192
Leonid Shifrin Avatar answered Oct 09 '22 04:10

Leonid Shifrin