1
$\begingroup$

Wanting to persist credentials entered via a dialog. While doing so I wanted to scope them by prepending a type to the symbol name. Came across this behavior which I find odd:

DeleteObject[LocalObjects[]]
f[key_] := Module[{},
  If[ValueQ[LocalSymbol[key]],
   Print["I have a value for " <> key],
   Print["No value for " <> key]
   ]
  ]

f[b] returns: No value for b

The trouble starts if I use a locally defined variable:

g[k_] := Module[{key = k},
  If[ValueQ[LocalSymbol[key]],
   Print["I have a value for " <> key],
   Print["No value for " <> key]
   ];
  ]

g["c"] returns: I have a value for c

key is still a string in the second definition - any idea why ValueQ[] thinks it is set?

I can probably manage scoping with a separate directory for each type, but why!?

$\endgroup$
0

1 Answer 1

4
$\begingroup$

A simpler version:

key = "c";
ValueQ @ LocalSymbol[key]

True

What's happening is that ValueQ has the attribute HoldAll:

Attributes[ValueQ]

{HoldAll, Protected, ReadProtected}

So, ValueQ is testing whether the unevaluated LocalSymbol[key] has a value, and of course it does. The value is LocalSymbol["c"]. It's basically the same thing as asking:

ValueQ[key]

True

$\endgroup$
2
  • 1
    $\begingroup$ It's worth mentioning that the problem will not occur if you use With instead of Module in the definition of g[k_]. $\endgroup$ Commented Sep 11, 2020 at 7:13
  • $\begingroup$ Thank you both. I guess a saner way to see if my LocalSymbol has been set may be to evaluate it and see what it's Head is. $\endgroup$
    – SEngstrom
    Commented Sep 15, 2020 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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