13

As noted elsewhere, you can list all user-defined symbols with this:

Names["Global`*"]

But I'd like to find just my global variables (I'm in the middle of some hairy debugging), not my function definitions. Something like this is close:

Select[Names["Global`*"], Head@Symbol[#]=!=Symbol && Head@Symbol[#]=!=Function&]

But that misses variables whose value is a symbol (perhaps I have x = Pi).

I could probably beat that thing into submission but maybe there's a cleaner, more direct way?

Community
  • 1
  • 1
dreeves
  • 26,430
  • 45
  • 154
  • 229

2 Answers2

15

If we consider any symbol with an own-value as a "variable", then this will do the trick:

ClearAll[variableQ]
variableQ[name_String] := {} =!= ToExpression[name, InputForm, OwnValues]

Select[Names["Global`*"], variableQ]

Note that this technique will fail on read-protected symbols and will misidentify some forms of auto-loaded functions.

Edit 1

As @Szabolcs points out, the definition of variableQ can be simplified if ValueQ is used:

variableQ[name_String] := ToExpression[name, InputForm, ValueQ]

Edit 2

As @dreeves points out, it might be desirable to filter out apparent variables whose values are functions, e.g. f = (#+1)&:

variableQ[name_String] :=
  MatchQ[
    ToExpression[name, InputForm, OwnValues]
  , Except[{} | {_ :> (Function|CompiledFunction)[___]}]
  ]

This definition could be easily extended to check for other function-like forms such as interpolating functions, auto-loaded symbols, etc.

WReach
  • 18,098
  • 3
  • 49
  • 93
  • 2
    Perfect; thank you! I may also want to exclude functions defined like `f = (#+1&)` which is easy to add a check for (just see whether the Head is Function, like I did in the question). But your solution is what you'd generally want. Thanks again. – dreeves Jul 18 '11 at 01:49
  • 6
    @WReach, @dreeves Related function: `ValueQ`. It's essentially the same: `variableQ[name_String] := ToExpression[name, InputForm, ValueQ]` – Szabolcs Jul 18 '11 at 07:40
  • 1
    @Szabolcs Actually, in general `ValueQ` is not so innocent, since in many cases it leaks evaluation - it evaluates things in the process of testing for a value (I discussed it here http://stackoverflow.com/questions/4599241/checking-if-a-symbol-is-defined/4621562#4621562 in more detail). For `OwnValues` though, it seems to be OK, so my comment is only tangentially relevant to the case at hand. – Leonid Shifrin Jul 18 '11 at 11:00
  • @Leonid, I'm aware of that, as it's possible to check the implementation of `ValueQ` (just remove the `ReadProtected` attribute). Yes, I should have mentioned that `ValueQ` is applicable to any expression, but will only guarantee that it won't evaluate that expression in the case of Symbols (our case). **EDIT:** I just noticed you present the implementation of `ValueQ` in the post you linked to as well. – Szabolcs Jul 18 '11 at 11:55
1

One might consider a variable to be a Global` symbol that does not pass FunctionQ.

Community
  • 1
  • 1
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125