In this question, there is a beautiful method to copy a symbol. However, i'm not able to use it as an addon to my package. So the main question is
How to rename/copy a function defined in a package by loading one of its sub packages ?
I'll try to explain that in an minimal example
Let's say I have a package A`
BeginPackage["A`"]
f::usage = "My function";
Begin["Private`"];
f[x_] := x^2;
End[]
EndPackage[];
Due to the fact, that f was earlier named g and I would like my old notebooks still to work (and though I can rewrite my package functions, I would like to have a kind of legacy package (okay I could also just copy my Package and load the old or the new one - despite debugging twice that works)), so I define something like
BeginPackage["A`Sub`"]
SetAttributes[copy,HoldFirst];
new_~copy~org_:=With[{prop={Attributes,UpValues,OwnValues,DownValues,SubValues,NValues,FormatValues,Messages,Options}},ClearAll@new;
Set[#@new,#@org/.HoldPattern@org:>new]&~Scan~prop;]
(* Start copying*)
g~copy~A`f;
EndPackage[];
(using the great idea of the copy from above). Here I'll use A`f to avoid shadowing problems (and put this Sub.m in the subdirectory A/ of the A.m).
But if I now try to use that, say in a notebook (ATest.nb inside the same directory as A.m)
$Path = Join[$Path, {NotebookDirectory[]}];
Needs["A`"];
Of course f works as intended, but loading
Needs["A`Sub`"];
does not make g available as a copy of f (and does neither report any error). Though, executing the cells of Sub.m directly one by one does. Of course, i don't want to specify g::usage because that should be obtained by copying from f. I think it might depend on the context, but I can't see why and how.
What am I missing here?
Update
As Albert pointed out, rm -rf s solution below should be extended using a Private` area for the copy function. Then the sub package providing the old names looks like the following
BeginPackage["A`Sub`",{"A`"}];
Begin["Private`"];
SetAttributes[copy,HoldFirst];
new_~copy~org_:=
With[{prop={Attributes,UpValues,OwnValues,DownValues,SubValues,NValues,FormatValues,Messages,Options}},
ClearAll@new;
Set[#@new,#@org/.HoldPattern@org:>new]&~Scan~prop;
];
(* Start copying*)
A`Sub`g~copy~A`f;
End[]
EndPackage[];
Then the right operand of copy (the original f) needs the context A` and the left one, g (in order not to be private) the context A`Sub` (due to the fact that ::usage should also be copied from f.
A`Sub`does not know aboutA`, so you should loadNeeds["A`"]immediately afterBeginPackage["A`Sub`"]. I haven't run your code, but can you try the above and see if it works (use a fresh kernel, etc.). If it does, I'll post it as an answer. – rm -rf Mar 01 '13 at 15:15BeginPackage["A`Sub`",{"A`"}](and learned about the double ticks), it works. Though my eyes hurt, that the subpackage has to load it's parent; but I'll have to get used to that I think. Works fine :) – Ronny Mar 01 '13 at 15:20BeginandEnd: as it is written now, you'll also exportcopy,prop,newandorgalong withg... – Albert Retey Mar 01 '13 at 16:00