8
$\begingroup$

I want to make private functions.for that purpose,I wrote the following code.

BeginPackage["Test1`"]
Begin["`Private`"]
function1[x_]:=x
End[]
EndPackage[]

I saved the above package and closed my entire Mathematica and again reopen Mathematica and evaluated that Package.

in Notebook I am calling the above function.just like in the following way.

 Test1`function1[5]
 Test1`Private`function1[5]

it returns output like.

 function1[5]
 5

that means,functions are working fine but the problem was If you evaluate Package second time and evaluate Notebook code it returns like in the following way.

5
5

why it's working like that.clearly I mention full contexts

How can I resolve

Fell Free,If you want edit my question.

Thank you

$\endgroup$

3 Answers 3

13
$\begingroup$
  1. After running your Package code the first time Test1` is added to the $ContextPath.

  2. When you call Test1`function1[5] the symbol function1 is created in the context Test1`

  3. After calling BeginPackage["Test1`"] and Begin["`Private`"] the $ContextPath is: {"Test1`","System`"}

  4. When you use function1 in function1[x_] := x it is found in the $ContextPath and therefore it parses as Test1`function1.

To avoid this, you need to either remove the symbol Test1`function1 from the context path before defining function1[x_] := x, or you need to give the context explicitly. Either of these should work:

BeginPackage["Test1`"];
Begin["`Private`"];
Test1`Private`function1[x_] := x
End[];
EndPackage[];

Or:

BeginPackage["Test1`"];
Remove[function1]
Begin["`Private`"];
function1[x_] := x
End[];
EndPackage[];

If you wish to completely reset the contents of Test1` every time the package is run you might use Remove["Test1`*"].

$\endgroup$
3
  • $\begingroup$ If I use Subbu instead of Private in your use-case1 code.still it's working,then what's the use of Private. as for my understanding,Private functions are not accessible from another Packages.But here If you call any private functions with full contexts in any another package.It's working fine. That means,we can't write the Private functions inMM. $\endgroup$
    – subbu
    Commented Apr 30, 2013 at 11:50
  • 3
    $\begingroup$ @subbu there is nothing special about Private as a context name; it is merely convention. Also, "private" doesn't mean cannot be read, it just means "should not conflict (collide) with." Are you trying to keep people from reading a function definition? You should look at ReadProtected and Locked (attributes) if that is the case. Please consider posting a new question describing what you want out of a "private" function if not. $\endgroup$
    – Mr.Wizard
    Commented Apr 30, 2013 at 11:53
  • $\begingroup$ ok.Thank you for your answers. $\endgroup$
    – subbu
    Commented Apr 30, 2013 at 11:56
4
$\begingroup$

If you insist to write code this way I think you should really try to understand what $ContextPath and $Context do and how BeginPackage,EndPackage, Begin and End control these.

As Mr. Wizard has explained the problem you are facing is that within the private part of the package Test1` is in $ContextPath, but not Test1`Private`. If neither Test1`function1 nor Test1`Private`function1 exist, no function1 can be found in $ContextPath and a new symbol is generated using the current value of $Context which is Test1`Private`. After an explicit call to Test1`function1 that symbol exists. When you load the package code after Test1`function1 exists, it will be found in $ContextPath and will be used for the definition in the private part and no private symbol Test`Private`function1 will be used or generated.

The following will put the private context which $Context points to before everything else in $ContextPath, so now the definition will be made to the private symbol even if the public symbol exists. This should solve your problem and doesn't need to make any changes to other symbols, whether they exist or not:

BeginPackage["Test1`"];
Begin["`Private`"];
PrependTo[$ContextPath, $Context];
function1[x_] := x;
End[];
EndPackage[];

You should be aware that such manual manipulations of $ContextPath might have unexpected side effects, so it should be used with some care. Considering this, it probably would be a good idea to explain more clearly what you try to achieve, my impression is that you are probably abusing the namespace functionality for something that probably could be achieved better with other means.

$\endgroup$
1
$\begingroup$

You could try this:

BeginPackage["Test1`"];
ClearAll[function1];
function1::usage = "test";
Begin["`Private`"];
function1[x_] := x
End[];
EndPackage[];

Using Test1`Private`function1 is despising the whole idea of using a package in the first place.

There is more information in tutorial/SettingUpMathematicaPackages (You can put this in the help browser.)

$\endgroup$
4
  • $\begingroup$ Really,I am not understood,what you are writing . why you are using ClearAll[function1]; function1::usage = "test";.I evaluated your code,your code is working quietly opposite to my requirements. Actually,we are defining the function as a Private but your code returns like in the following way 5 Test1Privatefunction1[5] $\endgroup$
    – subbu
    Commented Apr 30, 2013 at 11:08
  • $\begingroup$ No, you need to use Remove[function1]; $\endgroup$ Commented Apr 30, 2013 at 11:10
  • $\begingroup$ @ChrisDegnen where will I use Remove[function1]; code. $\endgroup$
    – subbu
    Commented Apr 30, 2013 at 11:15
  • $\begingroup$ @subbu Please see my answer. $\endgroup$
    – Mr.Wizard
    Commented Apr 30, 2013 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.