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?
ToExpressionis 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"]andxhas a value, it will evaluate to the value and notx$\endgroup$