When writing packages I met the following problem. The way I name helper functions is like
BeginPackage["test`"];
ClearAll@@Names[$Context<>"*"];
test0[]:=0;
test0`helper1[]:=0;
test0`helper2[]:=0;
...
EndPackage[];
When Get["test`"]
the public symbols under test`
will be cleared by ClearAll@@Names[$Context<>"*"];
but the symbols under test0`
are remained unchanged.
I need a fast way of searching and clearing all symbols under the contexts like symbol`*
, where symbol
s are from some specific contexts.
To set up and test the problem, the following codes generate 10 symbols for each of the 200 sub-contexts:
BeginPackage["test`"];
ToExpression["
test"<>#1<>"[]=0;
test"<>#1<>"`a"<>#2<>"[]=0;
"]&@@@Flatten[
Outer[List,ToString/@Range[200],ToString/@Range[10]],
1
];
EndPackage[];
Names["test`*"]//Shallow
Names["test1`*"]
Names["test2`*"]
The direct way of clearing these helper functions is like
clearHelper[contexts__] :=
(
{contexts}//Map[Names[#<>"*"]&]//
Map[ClearAll@Evaluate[#<>"`*",#<>"`*`*"]&,#,{2}]&;
);
which is rather inefficient
test1`a1[]
clearHelper["test`"]//Timing
test1`a1[]
In some days earlier I used another method of managing helper functions: each symbol with helper functions is tagged by
test0//hasHelpers
where hasHelpers
will store test0
into a public list $hasHelpers
shared by all packages. Then I abandoned this method since frequently appending symbols to list will slow down Get
and I'm tired of adding test0//hasHelpers
.
Is there some clever way of solving this problem?
Or are there editors or IDEs that can auto-complete contexts? e.g. symbols like test0`helper1[]
within BeginPackage["test`"]
or Begin["`Private`"]
will be parsed into *.wl
as
test`test0`helper1[]
automatically?
Names["test*`*"]
adequate? That syntax is also supported byClear
andRemove
. $\endgroup$test`
are certainly not fitted intotest*`*
. A feature I forgot to say is that the association from symbols liketestn
to the contextstestn`
can be quite sparse since only a few functions need helper functions. And the naive inefficient functionclearHelper
just traverses this association one by one. $\endgroup$Names["test*`*"]
I get{test0`helper1, test0`helper2, test0}
. Note the last one,test0
, which is in thetest`
context. $\endgroup$BeginPackage["Test`"]; test0; Begin["`Private`"] test0[]:=helper1[] ... .... End[]; EndPackage[]
. Then you could just doClearAll["`*", "`*`*"]
and still onlytest0
is exported from the package. $\endgroup$test`
are not named astest0
in REAL examples. $\endgroup$