Note: I put Simon's implementation on GitHub. Contributions welcome!
When trying to read the definition of already defined (package or built-in) symbols using Information
or FullDefinition
, the biggest inconvenience is that lots of distracting private context names appear in front of all symbol names.
Currently I am using a little function contextFreeDefinition[]
to avoid this problem. It will attempt to hide the most frequently appearing context name in the definition. contextFreeDefinition[]
is based on this answer.
Compare for example ClearAttributes[RunThrough, ReadProtected]; Information[RunThrough]
and contextFreeDefinition[RunThrough]
. The latter is a lot less cluttered because the System`Dump`
context is hidden in the definition. (I usually paste the output of this function into Workbench and re-indent it using the Source -> Format
context menu item for better readability)
Unfortunately contextFreeDefinition[]
does not always successfully hide contexts, for example try the following:
ImportString["1", "List"]; (* force Stub symbols to be loaded *)
System`Convert`TableDump`ImportList // contextFreeDefinition
and notice that several symbols (especially patterns) still have System`Convert`TableDump`
prepended. For example, I see the following in the FullDefinition
it prints:
protectRegEx[System`Convert`TableDump`s_String] :=
StringReplace[System`Convert`TableDump`s, $ProtectedCharacterRules]
The symbol System`Convert`TableDump`s
still has the context name prepended even though the function tried to hide exactly this context.
Question: How can contextFreeDefinition[]
be fixed so it always hides the context, or what other alternative approaches are there to read the definitions of in-memory symbols?
The code of contextFreeDefinition[]
.
Clear[commonestContexts, contextFreeDefinition]
commonestContexts[sym_Symbol, n_: 1] := Quiet[
Commonest[
Cases[Level[DownValues[sym], {-1}, HoldComplete],
s_Symbol /; FreeQ[$ContextPath, Context[s]] :> Context[s]], n],
Commonest::dstlms]
contextFreeDefinition::contexts = "Not showing the following contexts: `1`";
contextFreeDefinition[sym_Symbol, contexts_List] :=
(If[contexts =!= {}, Message[contextFreeDefinition::contexts, contexts]];
Internal`InheritedBlock[{sym}, ClearAttributes[sym, ReadProtected];
Block[{$ContextPath = Join[$ContextPath, contexts]},
Print@InputForm[FullDefinition[sym]]]])
contextFreeDefinition[sym_Symbol, context_String] :=
contextFreeDefinition[sym, {context}]
contextFreeDefinition[sym_Symbol] :=
contextFreeDefinition[sym, commonestContexts[sym]]
Understanding and using the function:
commonestContexts[sym, n]
will find the n
most frequently used contexts that are not in $ContextPath
in the definition of symbol sym
.
contextFreeDefinition[sym]
will print the FullDefinition
of sym
, hiding the commonest context that would appear there. It will also issue a message with the name of the context being hidden.
contextFreeDefinition[sym, {"Context1`", "Context2`", ...}]
will try to hide an explicitly given list of contexts.
System`Convert`TableDump`ImportList // contextFreeDefinition
-- would you please try to provide an example that works in version 7? $\endgroup$contextFreeDefinition
or one that will give a better suggestion on how to do this kind of system spelunking. $\endgroup$