1
$\begingroup$

The code setString[name_String, value_]:= Evaluate[Symbol[name]] = value fails whenever Symbol[name] has already been assigned a value.

I know of only one way to affect the symbol denoted by a string without triggering further evaluation, and that is the Clear function. Said function takes as arguments both symbols and strings denoting symbols. From this

setString[name_String, value_]:= Module[{}, 
Clear[name]; 
Evaluate[Symbol[name]] = value]

seems like the only solution.

This works, but is this the "correct" solution for the problem? It would not be possible without exploiting the "quirk" of Clear to take both symbols and symbol names. Are there any other solutions?

$\endgroup$
2
  • $\begingroup$ Mathematica could really use an “evaluate just until a pattern is matched” function imo—something that could maybe be written like Evaluate[Symbol[name], _Symbol], for example. $\endgroup$
    – thorimur
    Mar 23, 2021 at 9:26
  • 1
    $\begingroup$ I think it could be written, for what it’s worth! Mr. Wizard’s infamous (to me, anyway) step function could easily be adapted for the job. It would just be nice for it to be built in. If I get back to my computer and no one else has answered with something better, I’ll take a stab at it... $\endgroup$
    – thorimur
    Mar 23, 2021 at 9:29

3 Answers 3

1
$\begingroup$

This answer was suggested by @Jens in a comment to How to set a value to a symbol denoted by a string to work.

ClearAll[x,y,setString]
setString[name_String, value_] := (Clear[name]; 
  Activate[Inactive[Set][Symbol[name], value]])

x = 1;
setString["y", 2];
setString["x", 3];

{x,y}   (*  {3,2}  *)
$\endgroup$
1
$\begingroup$

I would use the following variation of Daniel's answer:

setString[s_String, v_] := ToExpression[s, StandardForm, Function[Null, #=v, HoldAll]]

Then:

val = 2;
setString["val", 5];
val

5

$\endgroup$
1
$\begingroup$

MMA evaluate arguments before feeding them to a function. Therefore, if Symbol[name] already has a value: value1

Evaluate[Symbol[name]] = value2

is equivalent to:

value1 = value2

what is an error.

To circumvent MMA's evaluation we may e.g. create first a string with the code to set the variable and afterwards execute this string:

setString[name_String, value_] := ToExpression[name <> "=" <> ToString[InputForm@value]];

with this:

val = 2;
setString["val", 5];
val

(*5*)
$\endgroup$
2
  • $\begingroup$ You should at least use InputForm in your ToString. Consider what happens with setString["val", 1/2]. $\endgroup$
    – Carl Woll
    Mar 23, 2021 at 16:14
  • $\begingroup$ Yes, nobody is perfect. I added this. Thank's $\endgroup$ Mar 23, 2021 at 19:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.