Adding to Szabolcs's answer, it's better to use ExtendedDefinition
instead of ExtendedFullDefinition
.
In situation in which old
symbol (the one that we want to copy), depends on anotherSymbol
and anotherSymbol
has old
symbol somewhere in it's ...Values
e.g.:
ClearAll[new, old, anotherSymbol]
old = anotherSymbol
anotherSymbol[] := 2 old
Full definition of old
includes definition of anotherSymbol
:
Language`ExtendedFullDefinition[old]
(* Language`DefinitionList[
old -> {
OwnValues -> HoldPattern[old] :> anotherSymbol, SubValues -> {},
UpValues -> {}, DownValues -> {}, NValues -> {}, FormatValues -> {},
DefaultValues -> {}, Messages -> {}, Attributes -> {}
},
anotherSymbol -> {
OwnValues -> {}, SubValues -> {}, UpValues -> {},
DownValues -> {HoldPattern[anotherSymbol[]] :> 2 old},
NValues -> {}, FormatValues -> {}, DefaultValues -> {},
Messages -> {}, Attributes -> {}
}
] *)
Assignment using ExtendedFullDefinition
:
Language`ExtendedFullDefinition[new] =
Language`ExtendedFullDefinition[old] /. HoldPattern[old] :> new
(* Language`DefinitionList[
new -> {
OwnValues -> HoldPattern[new] :> anotherSymbol, SubValues -> {},
UpValues -> {}, DownValues -> {}, NValues -> {}, FormatValues -> {},
DefaultValues -> {}, Messages -> {}, Attributes -> {}
},
anotherSymbol -> {
OwnValues -> {}, SubValues -> {}, UpValues -> {},
DownValues -> {HoldPattern[anotherSymbol[]] :> 2 new},
NValues -> {}, FormatValues -> {}, DefaultValues -> {},
Messages -> {}, Attributes -> {}
}
] *)
has a side effect. As we can see above, rule HoldPattern[old] :> new
changes not only possible self references of old
, discussed in Szabolcs's answer, but also references to old
in definition of anotherSymbol
.
By evaluating above assignment we have changed definition of anotherSymbol
:
?? anotherSymbol
(* Global`anotherSymbol
anotherSymbol[]:=2 new *)
Language`ExtendedDefinition
, in contrast to "Full" variant, returns and assigns only definition of symbol passed to it as argument.
ClearAll[new, old, anotherSymbol]
old = anotherSymbol
anotherSymbol[] := 2 old
Language`ExtendedDefinition[old]
(* Language`DefinitionList[
old -> {
OwnValues -> HoldPattern[old] :> anotherSymbol, SubValues -> {},
UpValues -> {}, DownValues -> {}, NValues -> {}, FormatValues -> {},
DefaultValues -> {}, Messages -> {}, Attributes -> {}
}
] *)
Assignment to ExtendedDefinition
:
Language`ExtendedDefinition[new] =
Language`ExtendedDefinition[old] /. HoldPattern[old] :> new
(* Language`DefinitionList[
new -> {
OwnValues -> HoldPattern[new] :> anotherSymbol, SubValues -> {},
UpValues -> {}, DownValues -> {}, NValues -> {}, FormatValues -> {},
DefaultValues -> {}, Messages -> {}, Attributes -> {}
}
] *)
is free of side effect of ExtendedFullDefinition
:
?? anotherSymbol
(* Global`anotherSymbol
anotherSymbol[]:=2 old *)
and of course correctly copies definition of old
to new
:
?? new
(* Global`new
new=anotherSymbol *)
clone
function of Leonid around, that does basically this. Don't forget Options, NValues, OwnValues, SubValues, Defaults. And make it HoldAll $\endgroup$org
refers toorg
in its definition, willnew
keep referring toorg
or tonew
? $\endgroup$