MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Second argument of BeginPackage, revisited

  • To: mathgroup at smc.vnet.net
  • Subject: [mg78546] Re: [mg78537] Re: Second argument of BeginPackage, revisited
  • From: Carl Woll <carlw at wolfram.com>
  • Date: Wed, 4 Jul 2007 05:29:07 -0400 (EDT)
  • References: <f5td66$36j$1@smc.vnet.net><f62k72$bod$1@smc.vnet.net> <200707031051.GAA02603@smc.vnet.net>

Andrew Moylan wrote:

>Right, there is no irregularity in the value of $ContextPath after
>executing EndPackage[]. As stated in the documentation, after the
>EndPackage[] statement corresponding to BeginPackage["a`"], only "a`"
>has been added to the original value of $ContextPath.
>
>The irregularity that I am referring to is in the different values of
>$ContextPath *between* the calls to BeginPackage[] and EndPackage[].
>Compare the output of these two examples:
>
>BeginPackage["a`", {"PhysicalConstants`"}]
>$ContextPath
>
>Output: {"a`", "PhysicalConstants`", "System`"}
>
>
>BeginPackage["a`"]
>Needs["PhysicalConstants`"]
>$ContextPath
>
>Output: {"PhysicalConstants`", "Units`", "a`", "System`"}
>
>
>As Don DuBois has pointed out in a private message, the correct way to
>obtain the behaviour of Needs[] when declaring packages is not to use
>the second argument of BeginPackage, but instead to use Needs[]
>*twice*, like this:
>
>BeginPackage["a`"]
>Needs["b`"]
>(* code block 2 *)
>EndPackage[]
>Needs["b`"]
>  
>
An alternative is to use

BeginPackage["a`", {"PhysicalConstants`", "Units`"}]

Carl Woll
Wolfram Research

>
>
>On Jul 2, 9:08 pm, dh <d... at metrohm.ch> wrote:
>  
>
>>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.
>>>      
>>>
>
>
>  
>



  • Prev by Date: Re: Working with factors of triangular numbers.
  • Next by Date: Re: Rotable Graphics and ViewPoint
  • Previous by thread: Re: Second argument of BeginPackage, revisited
  • Next by thread: Re: Suggestions for Maintaining "Object" State?