Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose I have a few symbols, one of which has a value:

{abc1, abc2 = 5, abc3};

I can use Names to get the list of names, as strings:

InputForm[names = Names["Global`abc*"]]
(* {"abc1", "abc2", "abc3"} *)

Now I want to find which symbols have values. This fails, because ValueQ expects the first argument to be a Symbol, not a String:

Select[names, ValueQ]
(* {} *)

This fails (with lots of messages), because ValueQ doesn't evaluate the argument enough:

Cases[names, st_ /; ValueQ[Symbol[st]]]
(* {"abc1", "abc2", "abc3"} *)

If we force evaluation, we go too far, and this fails because we get ValueQ[5] instead of ValueQ[abc2]:

Cases[names, st_ /; ValueQ[Evaluate[Symbol[st]]]]
(* {} *)

This approach works, but is far from elegant:

Cases[names, st_ /; ToExpression["ValueQ[" <> st <> "]"]]
(* "abc2" *)
share|improve this question
add comment

3 Answers

up vote 18 down vote accepted

I usually use

ToExpression["symbol",  InputForm, ValueQ]

ToExpression will wrap the result in its 3rd argument before evaluating it.


Generally, all functions that extract parts (Extract, Level, etc.) have such an argument. This is useful when extracting parts of held expressions. ToExpression acts on strings or boxes, but both the problem with evaluation control and the solution is the same. I thought this was worth mentioning here.

share|improve this answer
2  
Note that ValueQ is not innocent - it leaks evaluation. Here is some discussion, where I also contributed an answer with what is supposed to be a safer version of valueQ based on one-step evaluation: stackoverflow.com/questions/4599241/…. It is overly complex, I know it can be written better, but the point is to be wary of the system ValueQ, to avoid nasty surprises. –  Leonid Shifrin Jan 18 '12 at 20:55
    
@Leonid I think ValueQ is safe for as long as it's acting on a symbol only (i.e. is looking at OwnValues), but it evaluates the argument for anything else. Is this correct? I remember I looked at the implementation of ValueQ once (it's accessible) and concluded this, but that was a long time ago. –  Szabolcs Jan 18 '12 at 21:14
1  
Yes, I think I came to the same conclusions. Actually, in the linked SO discussion, I give some explicit example where it leaks evaluation. Can not dig in deeper now, need to get some sleep :). But for OwnValues only, there is a bullet-proof solution: (HoldComplete[sym]/.OwnValues[sym])=!=HoldComplete[sym] - very simple and robust. –  Leonid Shifrin Jan 18 '12 at 21:25
add comment

You can also use MakeExpression

ValueQ @@ MakeExpression["abc2"]
share|improve this answer
add comment

This one is a different method to access symbol names and values (I think it originates from MathGroup):

(edited to fit the original question)

Attributes[symbolToRule] = {HoldAll, Listable};
symbolToRule[sym_String] := HoldForm[sym] -> Head[Symbol[sym]] =!= Symbol;
symbolToRule[sym_Symbol] := HoldForm[sym] -> ValueQ[sym];

with symbols:

{a, b = 5, c};
rules = symbolToRule[{a, b, c}]
Pick[First /@ rules, Last /@ rules]

output:

Mathematica graphics

with strings:

rules = symbolToRule[{"a", "b", "c"}]
Pick[First /@ rules, Last /@ rules]

output:

Mathematica graphics

share|improve this answer
    
Ah, but you're using {a,b,c} instead of {"a","b","c"}. That's the tricky part... :-) –  Brett Champion Jan 18 '12 at 21:08
    
Ah, I see. Trying to cover this up cleverly... –  István Zachar Jan 18 '12 at 21:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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