I am working on the fancy abstraction for Block function. The idea is to use rules to specify which local variable will be used, even if it already defined in the global context
like this
str = "something in the global context";
localEval[str, "str"->"Hello"]
and the output will be
"Hello"
where the global definition of str
remains untouched.
I came up with the following solution, that works well
localEval[exp_, vars___] := With[
{args = With[{val = #[[2]]},
ToExpression[#[[1]], InputForm, Function[name, Hold[name = val], HoldAll]]
] & /@ List[vars]
},
Block[args,
exp
] // ReleaseHold
];
SetAttributes[localEval, HoldFirst];
but for me it is not fancy, because firstly it creates an error message, which doesn't affect anything
Block::lvsym: Local variable specification {Hold[str=hello]} contains Hold[str=hello], which is not a symbol or an assignment to a symbol.
I assume that ReleaseHold firstly tries to evaluate Block with the first argument contained Hold expressions and only after that goes to release them.
How could it be improved? Also I am worrying about the possible performance issues due to the error messages generated.
Block
,Module
, orWith
don't work for your application? I find your approach rather baffling. $\endgroup$Set
has the attributeHoldFirst, ypou may simply define:
localEval[str] = "Hello";` thenlocalEval[str]
will always return "Hello" independent of the value of str. $\endgroup$