Angenommen, ich ersetze eine Funktion eines Pakets, z. B. knitr:::sub_ext
. (Hinweis: Ich bin besonders interessiert, wo es eine interne Funktion ist, d. H. Nur zugänglich durch :::
im Gegensatz zu ::
, aber die gleiche Antwort kann für beide funktionieren).rufen Sie die ursprüngliche Version der Paketfunktion ab, selbst wenn sie überzugewiesen wurde
library(knitr)
my.sub_ext <- function (x, ext) {
return("I'm in your package stealing your functions D:")
}
# replace knitr:::sub_ext with my.sub_ext
knitr <- asNamespace('knitr')
unlockBinding('sub_ext', knitr)
assign('sub_ext', my.sub_ext, knitr)
lockBinding('sub_ext', knitr)
Frage: Gibt es eine Möglichkeit, die ursprünglichenknitr:::sub_ext
abzurufen, nachdem ich das getan habe? Vorzugsweise ohne das Paket neu zu laden?
(Ich kenne einige Leute wollen wissen, warum ich das wollen würde, dies zu tun, hier ist es. Nicht für die Frage Pflichtlektüre). Ich habe wie so einige Funktionen in Paketen Patchen (nicht eigentlich die sub_ext
Funktion ...):
original.sub_ext <- knitr:::sub_ext
new.sub_ext <- function (x, ext) {
# some extra code that does something first, e.g.
x <- do.something.with(x)
# now call the original knitr:::sub_ext
original.sub_ext(x, ext)
}
# now set knitr:::sub_ext to new.sub_ext like before.
Ich stimme dies nicht generell eine gute Idee ist (in den meisten Fällen handelt es sich schnelle Lösungen, bis Änderungen vornehmen ihren Weg in CRAN, oder sie sind "Feature Requests", die nie genehmigt werden würden, weil sie etwas fallspezifisch sind.
Das Problem mit dem oben genannten ist, wenn ich es versehentlich zweimal ausführen (z realknitr:::sub_ext
, so bekomme ich unendliche Rekursion.
Da sub_ext
eine interne Funktion (ich würde es nicht direkt aufrufen, sondern Funktionen von knitr wie knit
es nennen intern), kann ich nicht alle Funktionen zu ändern, hoffen, dass sub_ext
rufen new.sub_ext
manuell aufrufen , daher der Ansatz, die Definition im Paket-Namespace zu ersetzen.
AHh, vermutete ich so viel (unwiderruflich überschreiben den Wert). Ich hatte gehofft, man könnte so etwas wie "Knitr" in einer privaten/"frischen" Umgebung nachladen und den Wert von dort abrufen. Ich bin jedoch sehr glücklich darüber, dass ich den Wert zurücksetzen kann, wenn ich fertig bin (warum habe ich nicht daran gedacht ?!) und der Fall, der die Frage inspirierte, ist in der Tat ein Fall von Add-In-Codezeilen zu der existierenden Funktion, so kann ich sogar die "trace" -Methode verwenden (nett btw! nie wirklich 'trace' vorher verwendet). –
@ mathematic.coffee - Ich denke, Sie könnten immer so etwas tun, einen Systemaufruf verwenden, um die Definition der Funktion aus einer frischen R-Sitzung abzurufen: 'x <- system2 (" Rscript ", c (" - e ", shQuote) ('dput (knitr ::: sub_ext)')), stdout = TRUE); xx <- source (textConnection (x)) $ value; Umgebung (xx) <- asNamespace ("knitr"); assignInNamespace ("sub_ext", xx, asNamespace ("knitr")) '. Aber das scheint ziemlich lächerlich zu sein, oder ?! –
Danke, dass du mich mit 'trace' bekannt gemacht hast! – isomorphismes