14
$\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$
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$
  • $\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 Jan 17 '13 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 Jan 17 '13 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 Jan 17 '13 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 Jan 21 '13 at 16:39
  • $\begingroup$ Well, it's a useful data point. $\endgroup$ – Joel Klein Jan 22 '13 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$
  • $\begingroup$ Yes, that's interesting. Maybe a UniqueContext[], a counterpart to Unique, could help eliminate the dependence on Test`. $\endgroup$ – Joel Klein Jan 17 '13 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$ – Leonid Shifrin Jan 18 '13 at 8:00
  • $\begingroup$ @JoelKlein A UniqueContext[] would certainly help here. I take it it hasn't been implemented, though. $\endgroup$ – Emilio Pisanty Apr 15 '16 at 19:31
9
$\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$
  • 3
    $\begingroup$ Very useful! Would love to see stuff like that documented instead of additional famous person curves. $\endgroup$ – Kuba Sep 29 '17 at 10:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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