Suppose I have a list of names of Symbol
s:
f1 := Print["f1 is evaluated!"];
list = {"f1", "f2"};
The obvious way to Block
these Symbol
s 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 Symbol
s?
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]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With