Skip to main content
added 151 characters in body
Source Link

I don't have a solution, only a workaround:

undoCellContext[expr_] := Module[{ccSymbols, rules},
  ccSymbols = 
   Cases[expr, _Symbol, \[Infinity]] // DeleteDuplicates // 
    Select[StringStartsQ["$CellContext`"]@*ToString];
  rules = (# -> Symbol[SymbolName[#]]Symbol["Global`"<>SymbolName[#]]) & /@ ccSymbols;
  expr /. rules
  ]

Once[...,"Notebook"] // undoCellContext

As an optimization, when LeafCount[expr] is suitably large, undoCellContext could switch from building a list and deleting duplicates to populating a HashSet within the delayed rule given to Cases.

It would also perhaps help if undoCellContext held the expression, and the replacement symbols, unevaluated until it was done with it.

We could "Fix" Once on versions where it's misbehavinbg:

If[$VersionNumber<=14.,
  Unprotect[Once];
  Once`Private`$overridden = True;
  Once[expr__,"Notebook"] := Block[{Once`Private`$overridden = False},
    Once[expr, "Notebook"] // undoCellContext
  ] /; Once`Private`$overridden
  Protect[Once];
]

For reference, Once is not guilty. The underlying problem is that PersistentObject[...,"Notebook"]["Value"] converts Global</code> symbols to <code>$CellContext on readout.

I don't have a solution, only a workaround:

undoCellContext[expr_] := Module[{ccSymbols, rules},
  ccSymbols = 
   Cases[expr, _Symbol, \[Infinity]] // DeleteDuplicates // 
    Select[StringStartsQ["$CellContext`"]@*ToString];
  rules = (# -> Symbol[SymbolName[#]]) & /@ ccSymbols;
  expr /. rules
  ]

Once[...,"Notebook"] // undoCellContext

As an optimization, when LeafCount[expr] is suitably large, undoCellContext could switch from building a list and deleting duplicates to populating a HashSet within the delayed rule given to Cases.

We could "Fix" Once on versions where it's misbehavinbg:

If[$VersionNumber<=14.,
  Unprotect[Once];
  Once`Private`$overridden = True;
  Once[expr__,"Notebook"] := Block[{Once`Private`$overridden = False},
    Once[expr, "Notebook"] // undoCellContext
  ] /; Once`Private`$overridden
  Protect[Once];
]

For reference, Once is not guilty. The underlying problem is that PersistentObject[...,"Notebook"]["Value"] converts Global</code> symbols to <code>$CellContext on readout.

I don't have a solution, only a workaround:

undoCellContext[expr_] := Module[{ccSymbols, rules},
  ccSymbols = 
   Cases[expr, _Symbol, \[Infinity]] // DeleteDuplicates // 
    Select[StringStartsQ["$CellContext`"]@*ToString];
  rules = (# -> Symbol["Global`"<>SymbolName[#]]) & /@ ccSymbols;
  expr /. rules
  ]

Once[...,"Notebook"] // undoCellContext

As an optimization, when LeafCount[expr] is suitably large, undoCellContext could switch from building a list and deleting duplicates to populating a HashSet within the delayed rule given to Cases.

It would also perhaps help if undoCellContext held the expression, and the replacement symbols, unevaluated until it was done with it.

We could "Fix" Once on versions where it's misbehavinbg:

If[$VersionNumber<=14.,
  Unprotect[Once];
  Once`Private`$overridden = True;
  Once[expr__,"Notebook"] := Block[{Once`Private`$overridden = False},
    Once[expr, "Notebook"] // undoCellContext
  ] /; Once`Private`$overridden
  Protect[Once];
]

For reference, Once is not guilty. The underlying problem is that PersistentObject[...,"Notebook"]["Value"] converts Global</code> symbols to <code>$CellContext on readout.

Source Link

I don't have a solution, only a workaround:

undoCellContext[expr_] := Module[{ccSymbols, rules},
  ccSymbols = 
   Cases[expr, _Symbol, \[Infinity]] // DeleteDuplicates // 
    Select[StringStartsQ["$CellContext`"]@*ToString];
  rules = (# -> Symbol[SymbolName[#]]) & /@ ccSymbols;
  expr /. rules
  ]

Once[...,"Notebook"] // undoCellContext

As an optimization, when LeafCount[expr] is suitably large, undoCellContext could switch from building a list and deleting duplicates to populating a HashSet within the delayed rule given to Cases.

We could "Fix" Once on versions where it's misbehavinbg:

If[$VersionNumber<=14.,
  Unprotect[Once];
  Once`Private`$overridden = True;
  Once[expr__,"Notebook"] := Block[{Once`Private`$overridden = False},
    Once[expr, "Notebook"] // undoCellContext
  ] /; Once`Private`$overridden
  Protect[Once];
]

For reference, Once is not guilty. The underlying problem is that PersistentObject[...,"Notebook"]["Value"] converts Global</code> symbols to <code>$CellContext on readout.