# How to save a context into an expression?

BeginPackage["foo"];
bar;
Begin["Private"];
bar[] := bar[ $Context,$ContextPath];
End[];
EndPackage[];


So I'd like to have all information about foo stored in an expression.

It may be useful in something like How can I include functions from a package into a CDF file? where the package is spread over many files.

• DumpSave is not portable enough

• Save saves $Context and $ContextPath (everything what is not protected) together with all definitions so loading it will affect environment.

I can load it within additional Begin/EndPackage but I don't like it.

• I don't know how to use Language functions to do this.

So I can cook up a workaround but I'd like to ask if I'm not missing something obvious here.

Summing up, compressContext should take context name as input and output compressed string which one can later Get @ StringToStream @ Uncompress @ string.

Or whatever that can be used to load context back.

It seems you want to avoid saving definitions for any System symbols. Instead of blocking all of the unprotected symbols that could be used, another idea is to modify the InputForm format of Set and TagSet so that they are suppressed when applied to System symbols. For example:
compressContext[context_] := InternalInheritedBlock[{Set, TagSet, Internal$ContextMarks = True}, Unprotect[Set, TagSet]; Format[HoldPattern@TagSet[s_Symbol, __], InputForm] /; Context[Unevaluated[s]]=="System":=OutputForm[""]; Format[HoldPattern@Set[s_Symbol, __], InputForm] /; Context[Unevaluated[s]]=="System":=OutputForm[""]; Compress @ ToString[ Join @@ ToExpression[Names[context<>"*"], InputForm, FullDefinition], InputForm ] ]  For your example: BeginPackage["foo"]; bar; Begin["Private"]; bar[] := bar[$Context, $ContextPath]; End[]; EndPackage[];  Applying compressContext and uncompressing: compressContext["foo"] Uncompress @ %  "1:eJxTTMoPCvZhYGBIy89PSEosio5VsLJVgHGCK4tLUnMTVJzz80pSK0p0FNAEAhJLMmJjDAyNFEA\ EnAEAuIobbg==" "foobar[] := foobar[System\$Context, System\$ContextPath] " The space where the $Context and $ContextPath definitions used to live has been removed. Initial answer How about blocking $Context and $ContextPath so that they are protected? Block[{$Context,$ContextPath}, SetAttributes[{$Context, $ContextPath}, Protected]; Save["kuba.m","foo"] ] FilePrint["kuba.m"]  foobar[] := foobar[$Context, \$ContextPath]
P.S. I'm not sure what role compressedContext is supposed to play here.
• +1 I will have to modify it to filter out everything except of MyPackageContextName** because if I have e.g. Needs["PacletManager"] in my package and e.g. CreatePaclet is mentioned inside, it will be stored. And it is quite natural not to expect this ;) – Kuba Dec 15 '17 at 7:04