Re: question on Mathematica package loading.

From: Maxim (ab_def_at_prontomail.com)
Date: 11/01/04


Date: 1 Nov 2004 01:17:12 -0800

bill_bw_1000@yahoo.com (Bill) wrote in message news:<40daf724.0410301511.59355902@posting.google.com>...
> I have posted this question 3 days ago (oct 27) to the Mathematica
> news group, and as of today oct 30, it still has not shown up, I assume
> it was not allowed on that group.
>
> It might be possible becuase I put the word 'bug?' in the subject.
> So I am removing the word 'bug' from the subject and trying this
> newsgroup.
>
> I am posting the question here in the hope someone can help.
>
> cheers,
> Bill
>
> ----- post -------
>
> I am having hard time understanding why Mathematica is doing
> the following.
>
> To summarize, I create a simple package with one
> function test3[] in it. Load the package, and can call
> the function ok. I removed the 'usage' line, and try to call
> the function again, but it will not work AS expected. But this
> results in a new symbol added by the same name of the function,
> again as expected.
>
> But I then put the 'usage' line back into the package,
> clean the environment again, and reload the package,
> but I still can not access the package function again, it
> is still calling a fake symbol instead.
>
> ----- package file strange.m ----
>
> BeginPackage["strange`"]
> test3::usage="test3" <----- (1)
> Begin["`Private`"]
> test3[x_]:=x^3;
> End[]
> EndPackage[];
>
> ---- now test the package, we see we can call strange`test3[]
>
> <<strange.m
> Names["strange`*"]
> {test3}
> strange`test3[4]
> 64
>
> ----------------------
> Now edit the file strange.m, and remove the line
> marked by (1), so we now get
>
> BeginPackage["strange`"]
>
> Begin["`Private`"]
> test3[x_]:=x^3;
> End[]
> EndPackage[];
>
>
> ---- Now remove all symbols, and reload, we see the
> ---- name test3[] is not visible
>
> Remove["Global`*"]; Remove["strange`*"]; Names["strange`*"]
> {}
>
> Now load the packge again and try to call test3
>
> Get["strange.m"]; Names["strange`*"]
> {}
>
> You see, NO names in package. Now try to call strange`test3[],
> this will cause a new symbol to be created instead as expected:
>
> strange`test3[4]
> test3(4)
>
>
> Ok, now it seems to fix this, all what I have to do is
> to remove all the names in the strange context, and add the
> usage line back to the package, and reload, and then
> it should work. However, it still does not work.
>
> Added line(1) back, SAVED the package to disk again (file->save)
> then did
>
> Remove["Global`*"]; Remove["strange`*"]; Names["strange`*"]
> {}
>
> <<strange.m
> Names["strange`*"]
> {test3}
>
> -- so the name is back. OK. Now I would expect to be able
> -- to call it again and it should work as before. BUT it
> -- does not!
>
> strange`test3[4]
> test3(4) <----- This should come back as 64
>
>
> -- Why has not Mathematica call the correct function again??
> -- checked that there is NO global test3 function anywhere:
>
> Names["Global`test3"]
> {}
>
> -- So what is going on??

Let us see how your first package definition works:

BeginPackage["strange`"]
  test3::usage="test3"
  Begin["`Private`"]
    test3[x_]:=x^3;
  End[]
EndPackage[]

First BeginPackage makes strange` the current context; the usage line
isn't necessary per se, but its purpose is to create the symbol test3
in the current context strange` -- that is, it creates the symbol with
the full name strange`test3. Next we enter the context
strange`Private` and evaluate the expression test3[x_]:=x^3. The
parser sees two symbols: test3 and x. It searches for test3 and
successfully finds it, because strange` is on the context search path
($ContextPath) now, which is one of the functions of BeginPackage.
This means that you can access strange`test3 simply as test3.
Therefore, no new symbol strange`Private`test3 is created (but the
parser does create the new symbol strange`Private`x).

On the next step, when you remove the usage line, the symbol
strange`test3 isn't created; instead, when the evaluator reaches the
test3[x_]:=x^3 line, it cannot find the test3 symbol and creates the
new symbol strange`Private`test3. After the End[] statement you cannot
access this symbol directly as test3, because strange`Private` is not
put on the context search path (it's not the task of Begin/End) but
you can still access it by its full name, e.g. as
strange`Private`test3[3].

Finally, when you load the package with the usage line added again,
the symbol strange`test3 will be created once more, but what will
happen when we reach the test3[x_]:=x^3 line? The key point is that
the current context is always searched before the contexts on
$ContextPath. Therefore, the evaluator finds the symbol
strange`Private`test3 (left from the previous execution of the
package) and redefines it! In other words, that line will still look
like

strange`Private`test3[strange`Private`x_]:=strange`Private`x^3

just as during the second run (with the usage line removed) -- the
definition isn't attached to the strange`test3 symbol.

The bottom line is that all three examples work as expected and to get
the desired behaviour you should do Remove[strange`Private`test3].

Maxim Rytin
m.r@inbox.ru



Relevant Pages

  • Re: Blockbuster picks Blu-Ray - questions
    ... trotsky's use of the word "software" included digital downloads. ... However, that context doesn't include ... context that trotsky's usage lacked. ... deliberately correct and incorrect sentences, ...
    (rec.arts.movies.current-films)
  • Re: A transactionally consistent view on real-time data with MicroStrategy
    ... Create a context:, ... I tried using a global temporary table for storing a session specific ... and referencing a session specific package global variable in the "AS ... also post it to the MSTR user forums. ...
    (comp.databases.oracle.server)
  • Re: Question on Package Variables
    ... The package spec was as simple as they come; ... package variable can be directly accessed from SQL, ... heard of context switches. ... memory of the other context. ...
    (comp.databases.oracle.server)
  • Re: Perl Inheritance(take-2)
    ... I wanted to reflect the context structure into the code written by ... getting back the the example script, Package1 would be the base class, meaning ... package ContextBase; ... sub addContext { ...
    (perl.beginners)
  • Re: Blockbuster picks Blu-Ray - questions
    ... which is just not true under any context. ... trotsky's use of the word "software" included digital downloads. ... context that trotsky's usage lacked. ... deliberately correct and incorrect sentences, ...
    (rec.arts.movies.current-films)