# Why the Block command does not forget the $ContextPath variable I do not understand this behavior: method[args_] := (* forget the context path *) Block[{$ContextPath},
(* should given nothing, right? *)
Print["cpath=", $ContextPath]; ...  but when evaluated it gives the full context path (i.e. it does not forgets it). Why is that? This is against everything I (seem to) know about the Block function. - Next followup question: "How do I make a special variable like these?" ;-) – Szabolcs Feb 28 at 15:41 ## 2 Answers If I try this, everything gets removed except for {System,Global}: In[1]:=$ContextPath

Out[1]= {"PacletManager", "QuantityUnits", "WebServices", "System", "Global"}

In[2]:= Block[{$ContextPath}, Print[$ContextPath]]

During evaluation of In[2]:= {System,Global}


My guess is that this is a special exception which is implemented to make $ContextPath usable like this: Block[{$ContextPath}, Needs["SomePackage"]]


This loads the package without adding it to the context path. It's quite useful with Combinatorica in version 8 and later.

It is in fact possible to remove System and Global from $ContextPath but this just breaks the system completely and would also make it impossible to load any packages. You can (in a new session, where you won't lose work!!) try $ContextPath = {} and render the system unusable if you are using a notebook interface. The reason why package loading would be broken is that System context symbols would need to be referenced by the full name, as in SystemSin, which packages don't do.

So I think this is a special exception to the behaviour of Block/$ContextPath that makes the above use case possible. - +1 for tip on loading w/o adding to path. – rasher Feb 28 at 23:59 @rasher I learned it form Leonid but I don't remember in which answer. – Szabolcs Mar 1 at 0:01 @rasher Probably Szabolcs referred to this one. – Leonid Shifrin Mar 1 at 18:29 @LeonidShifrin Precisely. – Szabolcs Mar 1 at 18:29 That was fast :) – Leonid Shifrin Mar 1 at 18:30 There are some "special variables" in Mathematica that cannot be cleared. These are fundamentally necessary for its operation and while it will let you revert to a default value inside a Block, it will not allow you to clear it. You can verify this directly, without Block: Clear@$ContextPath


Clear::spsym: Special symbol $ContextPath cannot be cleared. >> It doesn't work even though $ContextPath is not Protected or Locked.

You can find out which other symbols are special:

Reap[Quiet@Check[Clear@#, Sow@#, Clear::spsym] & /@
Select[Names["System*"], FreeQ[Attributes@#, Protected] &]] // Last // Last

(* {$ActivationGroupID,$ActivationKey,$ActivationUserRegistered,$AssertFunction,$Assumptions,$BatchInput,$BoxForms,$CharacterEncoding,$Context,$ContextPath,$HistoryLength,$InputFileName,
$InstallationDirectory,$IterationLimit,$Language,$LicenseExpirationDate,$LicenseID,$LicenseProcesses,$LicenseServer,$LicenseSubprocesses,$LicenseType,$LoadedFiles,
$MachineAddresses,$MachineDomain,$MachineDomains,$MachineID,$MachineName,$MaxExtraPrecision,
$MaxLicenseProcesses,$MaxLicenseSubprocesses,$MaxPiecewiseCases,$MaxPrecision,$MaxRootDegree,$MinPrecision,$ModuleNumber,$NetworkLicense,$NumberMarks,$ParentLink,$ParentProcessID,$PasswordFile,$PatchLevelID,$Path,$ProcessID,$RandomState,$RecursionLimit,$TemporaryDirectory,$TemporaryPrefix,$TopDirectory,$TraceOff,$TraceOn,$TracePattern,$TracePostAction,$TracePreAction,$UserBaseDirectory,\$UserName} *)
`

From a quick look at what's in the list, you can easily see that most of these are critical for the software to function.

-