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.
>
>