I need to create a user-defined Block
function where the Block
variables' values are defined by code. For example, imagine I have:
SetAttributes[myBlock1,HoldAll]
myBlock1[args_]:=Block[{a=1,b=2,c=3,d=4},args]
myBlock1[{a,b,c,d}]
{1, 2, 3, 4}
Now, what I need is something like:
SetAttributes[myBlock2,HoldAll]
varList={"a","b","c","d"};
myBlock2[args_]:=Module[{varArgs},
varArgs=MapIndexed[ToString@Row[{#1,"=",#2[[1]]}]&,varList];
ToExpression@ToString@Row[{"Block[",varArgs,",",ToString@args,"]"}]
]
myBlock2[{a,b,c,d}]
{1, 2, 3, 4}
The above function works, but it's very clumsy (using ToExpression
) and error-susceptible. I tried something like:
SetAttributes[myBlock3,HoldAll]
varList={"a","b","c","d"};
myBlock3[args_]:=ReleaseHold[Hold@Block[varDef,args]/.varDef:>MapIndexed[(Evaluate@Symbol[#1]=#2[[1]])&,varList]]
myBlock3[{a,b,c,d}]
But without success in the "variables injection." One important point is that a
, b
, c
and d
should not escape from the block scope. How can I do that?
ToExpression
is your saviour $\endgroup$ToExpression
. :) $\endgroup$ToExpression
? A simple variation likemyBlock2[r={1,2,3};r[[b]]]
do not work with this solution, but is ok with the first one. $\endgroup$Symbol["x"]
andx
has a value, it will evaluate to the value and notx
$\endgroup$