Wie funktioniert das PACKAGE-Argument für .Call?

8

.Call scheint eher schlecht dokumentiert zu sein; ?.Call gibt eine Erklärung für das Argument PACKAGE :

  

PACKAGE : Wenn angegeben, beschränken Sie die Suche nach einer Zeichenkette .NAME auf die durch dieses Argument angegebene DLL (plus die konventionelle Erweiterung '.so', '.dll', ...).

     

Dieses Argument folgt ... und daher kann der Name nicht abgekürzt werden.

     

Dies soll Sicherheit für Pakete hinzufügen, die sicherstellen können, dass mit diesem Argument kein anderes Paket ihre externen Symbole überschreiben kann, und auch die Suche beschleunigt (siehe 'Hinweis').

Und in der Anmerkung:

  

Wenn eine dieser Funktionen häufig verwendet werden soll, geben Sie PACKAGE an (um die Suche auf eine einzelne DLL einzuschränken) oder übergeben Sie .NAME als eines der nativen Symbolobjekte. Die Suche nach Symbolen kann lange dauern, besonders wenn viele Namespaces geladen sind.

     

Sie können PACKAGE = "base" für in R verknüpfte Symbole sehen. Verwenden Sie dies nicht in Ihrem eigenen Code: Solche Symbole sind nicht Teil der API und können ohne Warnung geändert werden.

     

PACKAGE = "" wurde früher akzeptiert (war aber nicht dokumentiert): es ist jetzt ein Fehler.

Aber es gibt keine Anwendungsbeispiele.

Es ist unklar, wie das Argument PACKAGE funktioniert. Wenn ich zum Beispiel diese Frage beantworte, dachte ich, das Folgende sollte haben gearbeitet, aber es tut nicht:

%Vor%

Stattdessen funktioniert das:

%Vor%

Liegt das daran, dass C_BinCount nicht exportiert wird? Das heißt, wenn der interne Code von hist.default PACKAGE = "graphics" hinzugefügt hätte, hätte dies funktioniert?

Das scheint einfach zu sein, aber es ist sehr selten, dieses Argument zu verwenden; Keine der Quellen, die ich gefunden habe, geben mehr als nur eine kurze Erwähnung ( 1 , 2 , 3 , 4 , 5 ) ... Beispiele für diese tatsächlich Arbeit würde geschätzt werden (auch wenn es nur zitiert Code in einem vorhandenen Paket findet)

(für die Selbstbeschränkung, wenn Sie Code von der anderen Frage nicht kopieren möchten, hier sind x und breaks ):

%Vor%     
MichaelChirico 18.07.2016, 14:49
quelle

1 Antwort

10

C_BinCount ist ein Objekt der Klasse "NativeSymbolInfo" und nicht eine Zeichenkette, die eine C-Level-Funktion benennt, daher ist PACKAGE (das "die Suche nach einer Zeichenkette .NAME beschränkt") nicht relevant. C_BinCount wird durch die Erwähnung in useDynLib() im Grafikpaket NAMESPACE .

Als ein R-Symbol unterliegt die C_BinCount -Auflösung den gleichen Regeln wie andere Symbole - sie wird nicht aus dem NAMESPACE exportiert, also nur über graphics:::C_BinCount . Und auch aus diesem Grund für eine robuste Code-Entwicklung tabu. Da der C-Einstiegspunkt als Symbol importiert wird, ist nicht als Zeichenkette verfügbar, daher funktioniert .Call("C_BinCount", ...) nicht.

Wenn Sie ein NativeSymbolInfo-Objekt verwenden, wird R mitgeteilt, wo sich der C-Code befindet. Daher müssen Sie dies nicht erneut über PACKAGE tun. Die Wahl, das Symbol anstelle der Zeichenkette zu verwenden, wird vom Paketentwickler getroffen, und ich denke, dass dies im Allgemeinen als gute Praxis angesehen wird. Viele Pakete, die vor der Erfindung von NativeSymbolInfo entwickelt wurden, verwenden das Argument PACKAGE. Wenn ich den Quelltextbaum des Bioconductors grep, gibt es 4379 Zeilen mit .Call. * PACKAGE, zB hier .

Weitere Informationen, einschließlich Beispiele, finden Sie im Abschnitt zum Schreiben von R-Erweiterungen 1.5 .4 .

    
Martin Morgan 18.07.2016, 15:10
quelle

Tags und Links