16
$\begingroup$

I'd like to have a function, whether built-in or not, that when given a symbol, whether bound to a value or not, returns a string giving the context and name of the symbol.

Example: f[a] returns "Global`a"

Example: f[Developer`$MaxMachineInteger] returns "Developer`$MaxMachineInteger"

$\endgroup$

3 Answers 3

11
$\begingroup$

This is a variation of Leonid's answer that avoids the dependence on a context like "Test`" that must be empty:

SetAttributes[fq, {Listable, HoldAll}];

fq[sym_] := Block[{Internal`$ContextMarks = True},ToString[Unevaluated[sym]]]

fq[{fq, Print, Developer`$MaxMachineInteger}]

(* {"Global`fq", "System`Print", "Developer`$MaxMachineInteger"} *)
$\endgroup$
1
  • 3
    $\begingroup$ Very useful! Would love to see stuff like that documented instead of additional famous person curves. $\endgroup$
    – Kuba
    Commented Sep 29, 2017 at 10:14
10
$\begingroup$

This works, though it'd be nicer to have a built-in way to do it:

SetAttributes[fullyQualifiedName, {HoldAll, Listable}];
fullyQualifiedName[a_] := Context[a] <> SymbolName[Unevaluated@a]

Some demonstrations:

In[4]:= fullyQualifiedName[a]

Out[4]= "Global`a"

In[5]:= foo = 3

Out[5]= 3

In[6]:= fullyQualifiedName[foo]

Out[6]= "Global`foo"

In[7]:= fullyQualifiedName[Plot]

Out[7]= "System`Plot"

In[9]:= fullyQualifiedName[Developer`$MaxMachineInteger]

Out[9]= "Developer`$MaxMachineInteger"
$\endgroup$
5
  • $\begingroup$ I bit of poking around reveals that (at least in v7) the system function Information also uses Context therefore I suppose this is the canonical method. $\endgroup$
    – Mr.Wizard
    Commented Jan 17, 2013 at 13:26
  • $\begingroup$ @Mr.Wizard: Sadly no, Information only prints things, it doesn't return a string. I want to use this programmatically, not interactively. $\endgroup$
    – Joel Klein
    Commented Jan 17, 2013 at 14:42
  • $\begingroup$ Sorry, I didn't make myself clear. What I mean is Information uses basically the same method you posted above, so I doubt a "better" way exists or the developers would have used it. I think your answer is the canonical method. $\endgroup$
    – Mr.Wizard
    Commented Jan 17, 2013 at 15:44
  • 2
    $\begingroup$ You didn't have your employer information in your profile when I wrote the comment above and now it looks quite silly. Oh well. $\endgroup$
    – Mr.Wizard
    Commented Jan 21, 2013 at 16:39
  • $\begingroup$ Well, it's a useful data point. $\endgroup$
    – Joel Klein
    Commented Jan 22, 2013 at 2:23
9
$\begingroup$

Here is an alternative:

ClearAll[f];
SetAttributes[f, HoldAll];
f[a_Symbol] :=      
   Block[{$ContextPath = {"Test`"}, $Context = "Test`"},
      ToString[Unevaluated@a]
   ];

It is based on the way Mathematica treats short and long names depending on the current settings of $Context and $ContextPath. The context "Test`" must not exist for it to be fully bulletproof (it will produce short names for symbols in "Test`" otherwise), you can use some random string for it. The function produces the same output as yours. You can make it Listable as well, but for speed, it may be better to add a special rule for a list of symbols, so that the context is changed only once.

$\endgroup$
3
  • $\begingroup$ Yes, that's interesting. Maybe a UniqueContext[], a counterpart to Unique, could help eliminate the dependence on Test`. $\endgroup$
    – Joel Klein
    Commented Jan 17, 2013 at 4:30
  • $\begingroup$ @JoelKlein Having UniqueContext[] would be quite handy, and not only for this problem. It would have to be efficient, however (e.g. Contexts[] can be quite slow). $\endgroup$ Commented Jan 18, 2013 at 8:00
  • $\begingroup$ @JoelKlein A UniqueContext[] would certainly help here. I take it it hasn't been implemented, though. $\endgroup$ Commented Apr 15, 2016 at 19:31

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.