Re: Second argument of BeginPackage, revisited
- To: mathgroup at smc.vnet.net
- Subject: [mg78462] Re: Second argument of BeginPackage, revisited
- From: dh <dh at metrohm.ch>
- Date: Mon, 2 Jul 2007 06:53:37 -0400 (EDT)
- References: <f5td66$36j$1@smc.vnet.net><f5vs13$keg$1@smc.vnet.net> <f62k72$bod$1@smc.vnet.net>
Hi Andrew, you are correct, BeginPackage["a`",{"b`",..}].. EndPackage[] will put all the additional contexts "b`".. into $ContextPath. Therefore, all variables exported by these contexts will be available. On the other hand, BeginPackage["a`"] Needs["b`"];.. Endpackage[] will only put "a`" into $ContextPath, therefore, variables from "b`".. are not available afterwards. Daniel Andrew Moylan wrote: > On Jun 28, 6:37 pm, dh <d... at metrohm.ch> wrote: >> Hi Andrew, >> >> you misunderstood the Package concept. BeginPackage["a`", {"b`"}] will >> >> place b in the $ContextPath so that its content can be found, but it >> >> does not put b in Context[], so that new variables are not created in b. >> >> The following may help. Start a new session and enter: >> >> BeginPackage["b`",{"PhysicalConstants`"}] >> >> Print[SpeedOfLight]; >> >> Print[Context[]]; >> >> Print[$ContextPath]; >> >> EndPackage[] >> >> hope this helps, Daniel >> >> Andrew Moylan wrote: >>> Unfortunately (in my opinion), BeginPackage["a`", {"b`"}] does not *quite* >>> call Needs[] on its second argument(s). >>> Suppose b.m looks like this: >>> BeginPackage["b`", {"PhysicalConstants`"}] >>> (* some code *) >>> EndPackage[] >>> Then calling Needs["b`"] in a new kernel results in "PhysicalConstants`" >>> being on the list of contexts, so that e.g. SpeedOfLight works as expected. >>> But calling BeginPackage["a`", {"b`"}] instead does *not* put >>> PhysicalConstants on the list of contexts during the definition of the >>> package, so that e.g. SpeedOfLight results in the creation of a new, useless >>> symbol called a`SpeedOfLight. >>> Finally, for maximum confusion (in my opinion), once EndPackage[] is called >>> to finish loading the "a`" package, "PhysicalConstants`" *is* placed on the >>> list of contexts, causing shadowing between a`SpeedOfLight and >>> PhysicalConstants`SpeedOfLight. >>> Effectively, BeginPackage appears to >>> 1. Call Needs[] on its second arguments, then >>> 2. Temporarily remove from the context path any extra contexts those >>> packages added to the context path, then finally >>> 3. Put all those temporarily removed packages back onto the context path >>> once EndPackage[] is called. >>> Can anyone help me understand why this behaviour is useful? > > Daniel, you have misunderstood the question in my post. > > Here is the crucial irregularity to which I refer: > > BeginPackage["a`", {"b`"}] > (* code block 1 *) > EndPackage[] > > BeginPackage["a`"] > Needs["b`"] > (* code block 2 *) > EndPackage[] > Needs["b`"] > > The above two alternatives are not identical, because (strangely, in > my opinion) code in code block 1 cannot refer to symbols defined in > any packages declared in the second argument of the BeginPackage > statement for b` (in b.m); whereas code in code block 2 *can* refer to > such symbols. > > Here is a different way to understand the irregularity: > > Suppose this code works correctly: > > Needs["b`"] > (* code block 3 *) > > Then, will this code generally also work correctly? > > BeginPackage["whatever`", {"b`"}] > (* code block 3 *) > > The answer is no, because of the way BeginPackage apparently modifies > the value of $ContextPath after calling Needs[] on its second argument. > >