The following code works when evaluated in a notebook:
Person[name_String, age_Integer] := {name, age};
Person["Jane", 30]
name = "Dick";
age = 28;
Person[name, age]
Output
{"Jane", 30}
{"Dick", 28}
So I put it in the following package:
Person.m
BeginPackage["Person`"]
Unprotect @@ Names["Person`*"];
ClearAll @@ Names["Person`*"];
Person[name_String, age_Integer] := {name, age};
Protect @@ Names["Person`*"];
EndPackage[]
Person.nb
Needs["Person`"];
Person["Jane", 30]
name = "Dick";
age = 28;
Person[name, age]
name1 = "Bill";
age1 = 40;
Person[name1, age1]
Output
{"Jane", 30}
Set::wrsym: Symbol name is Protected. >>
Set::wrsym: Symbol age is Protected. >>
Person[name, age]
{"Bill", 40}
I don’t understand why there is a protection issue using symbols name and age. Are Person’s arguments “name” and “age” being protected too?
celtschk’s answer allowed me to see the light. The following does not expose name and age:
BeginPackage["Person`"]
Unprotect @@ Names["Person`*"];
ClearAll @@ Names["Person`*"];
Person::usage = "Person";
Begin["`Private`"]
Person[name_String, age_Integer] := {name, age};
End[]
Protect @@ Names["Person`*"];
EndPackage[]
Since when you define your function
Person, the current context isPerson`, all new identifiers are created there, even the identifiersnameandage(you didn’t create them before, therefore they are created at that point). Afterwards you protect everything in contextPerson`, including those two symbols. When you then try to assign to them, Mathematica correctly complains that they are protected.