7

Is there a way to set what symbols's definitions I do not want to store?

Consider the following code:

f := $MachineID;
SetDirectory[NotebookDirectory[]];
Save["testm.m", f];

ClearAll@f

<< "testm.m"
f
Set::specset: Cannot change the value of special symbol $MachineID. >>
0000-00000-00001 (*id of storing machine*)
0000-00000-00002 (*id of getting machine*)

This happens bacause testm.m contains:

f := $MachineID
$MachineID = "0000-00000-00001"

Questions:

  • Is there nicer way to avoid this than my approach:

    f:= Symbol["MachineID"] 
    

    ?

  • Is it Protected attribute which decides what is going to be stored? Because there is no problem if f:=SystemID but:

    Attributes[{$SystemID, $MachineID}]
    
    {{Locked, Protected}, {}}
    

Edit:

  • Why MachineID is not protected? - The bounty is founded for this question.
Kuba
  • 136,707
  • 13
  • 279
  • 740
  • Nice question! I agree that it seems odd that $MachineID is not Protected – Jacob Akkerboom Aug 27 '13 at 11:42
  • @JacobAkkerboom Hello,:) yes, in fact I wouldn't have known this but there is something else what causes the error msg and without this my MachineID could have been distributed :D. – Kuba Aug 27 '13 at 11:45
  • ah yes, I guess that could be a privacy issue. – Jacob Akkerboom Aug 27 '13 at 12:03
  • 2
    I am unhappy that you have asked two very different questions here causing two separate answer threads to come into existence for this one question. It makes a confusing mess for anyone trying to figure out what this post is really about. You really should have posted two questions. – m_goldberg Aug 27 '13 at 21:46
  • @m_goldberg You are right. I was too hasty (again :() and the question was evolving, even though it was posted, and ended up not well suited for the site. I will try rephrase it tomorrow so it will fit the answers and the leftovers move to the separate question. – Kuba Aug 27 '13 at 22:21
  • @JacobAkkerboom You are looking for answer why those symbols are not protected? I should have made a separate question but I had no time to focus on this :/ – Kuba Sep 02 '13 at 10:13
  • Yes, that's what I am looking for. Also maybe this is something that should be brought to WRI's attention, maybe it is simply an oversight. Also I like the question, as it seems quite likely somebody might encounter this undesired behavior. – Jacob Akkerboom Sep 02 '13 at 10:35
  • @JacobAkkerboom I agree with m_goldberg that this not well stated question but I think bounty can't be canceled so it has to stay as it is. My faul, I was too lazy to restate it. Is possible to edit bounty comment? maybe you coauld add that's about not protected symbols. If not, give here a comment, I will +1 it so it will be on top. – Kuba Sep 02 '13 at 10:40
  • Hm, I do not mind the question being a bit composite. I suppose the bounty will draw attention to the Q&A anyway, so that maybe a WRI employee will react. If you feel a new Q&A should be made for the question why it is protected, feel free to do so. – Jacob Akkerboom Sep 02 '13 at 13:02
  • @JacobAkkerboom Too late, let's leave it in this form :), I've removed redundant parts so it is clearer. I hope that your bound will result in an interesting answer :) – Kuba Sep 02 '13 at 13:06
  • 1
    Related: Why the Block command does not forget the $ContextPath variable. Perhaps we should investigate the extent of this relation, rm-rfs list is similar to mine, but not the same. – Jacob Akkerboom Mar 12 '14 at 11:21
  • Not being protected also creates problems with SaveDefinitions->True in DynamicModules and Manipulates. I have this issue with $MachineID and $UserName. – Gustavo Delfino Jul 24 '17 at 14:18
  • @GustavoDelfino yep, I don't use SaveDefinitions, it is nice for small cases but in general I work with: https://mathematica.stackexchange.com/a/86707/5478 – Kuba Jul 24 '17 at 14:39

2 Answers2

7

From the documentation:

Save: Save uses FullDefinition to include subsidiary definitions.

FullDefinition: FullDefinition[symbol] recursively prints as all definitions for the symbol, and for the symbols that appear in these definitions, unless those symbols have the attribute Protected.

So if you want to not save $MachineID you could do:

Protect[$MachineID];
Save["testm.m", f];
Unprotect[$MachineID];
jVincent
  • 14,766
  • 1
  • 42
  • 74
3

Extended comment

I found the following interesting. I guess this happens for more Symbols than just $MachineID. The following tries to assign to special symbols starting with a $ and gives an overview of whether that was allowed and what the attributes are. Warning: you may want to restart the kernel after this.

list =
  Function[
      xxxx, {HoldForm[xxxx], Check[xxxx = xxxx; "succes", "failure"], 
       Sequence @@ Attributes[xxxx]}, HoldAllComplete] @@ 
     ToExpression[#, InputForm, HoldComplete] & /@ 
   DeleteCases[Names["$*"], "$PrePrint" | "$Pre" | "$Post"];
list // TableForm
(*gives a big table*)

The following then gives a list of symbols similar to $MachineID in this respect

Select[list, 
  Function[Not[FreeQ[#, "failure"]] && FreeQ[#, Protected]]] // Column


(*output*)

    {$ActivationGroupID,failure}
    {$ActivationKey,failure}
    {$ActivationUserRegistered,failure}
    {$InputFileName,failure}
    {$LicenseExpirationDate,failure}
    {$LicenseID,failure}
    {$LicenseProcesses,failure}
    {$LicenseServer,failure}
    {$LicenseSubprocesses,failure}
    {$LicenseType,failure}
    {$MachineAddresses,failure}
    {$MachineDomain,failure}
    {$MachineDomains,failure}
    {$MachineID,failure}
    {$MachineName,failure}
    {$MaxLicenseProcesses,failure}
    {$MaxLicenseSubprocesses,failure}
    {$NetworkLicense,failure}
    {$ParentProcessID,failure}
    {$PatchLevelID,failure}
    {$ProcessID,failure}
    {$UserName,failure}
Jacob Akkerboom
  • 12,215
  • 45
  • 79