667 votes

Comment puis-je afficher le code source pour une fonction ?

J'ai envie de regarder le code source d'une fonction pour voir comment il fonctionne. Je sais que je peux imprimer une fonction en tapant son nom à l'invite de commandes:

> t
function (x) 
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>

Dans ce cas, qu'est - UseMethod("t") moyenne? Comment puis-je trouver le code source qui est effectivement utilisé, par exemple: t(1:10)?

Dans d'autres cas, il y a un peu de R code, mais la plupart du travail semble être fait ailleurs.

> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
{
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
    .Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow), 
        missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call)  .Primitive(".Internal")
> .Primitive
function (name)  .Primitive(".Primitive")

Comment puis-je savoir ce que l' .Primitive fonction? De même, certaines fonctions d'appel .C, .Call, .Fortran, .Externalou .Internal. Comment puis-je trouver le code source pour ceux?

616voto

Joshua Ulrich Points 68776

UseMethod("t") est de vous dire que l' t() est un (S3) de la fonction générique qui possède des méthodes pour les différentes classes d'objets.

Le S3 méthode de système de répartition

Pour les S3 classes, vous pouvez utiliser l' methods fonction pour lister les méthodes pour un générique de classe ou de fonction.

> methods(t)
[1] t.data.frame t.default    t.ts*       

   Non-visible functions are asterisked
> methods(class="ts")
 [1] aggregate.ts     as.data.frame.ts cbind.ts*        cycle.ts*       
 [5] diffinv.ts*      diff.ts          kernapply.ts*    lines.ts        
 [9] monthplot.ts*    na.omit.ts*      Ops.ts*          plot.ts         
[13] print.ts         time.ts*         [<-.ts*          [.ts*           
[17] t.ts*            window<-.ts*     window.ts*      

   Non-visible functions are asterisked

"Non visible fonctions marquées d'un astérisque sont" signifie que la fonction n'est pas exporté à partir de son paquet de noms. Vous pouvez toujours voir son code source via l' ::: de la fonction, ou par l'utilisation d' getAnywhere(). getAnywhere() est utile parce que vous n'avez pas à connaître la formule de la fonction de la provenance.

> getAnywhere(t.ts)
A single object matching ‘t.ts' was found
It was found in the following places
  registered S3 method for t from namespace stats
  namespace:stats
with value

function (x) 
{
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>

Le S4 méthode de système de répartition

Le S4 système est une nouvelle méthode de système de répartition et est une alternative à la S3. Voici un exemple d'un S4 fonction:

> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"

function (x, ...) 
standardGeneric("chol2inv")
<bytecode: 0x000000000eafd790>
<environment: 0x000000000eb06f10>
Methods may be defined for arguments: x
Use  showMethods("chol2inv")  for currently available ones.

La sortie offre déjà beaucoup d'informations. standardGeneric est un indicateur d'un S4 fonction. La méthode pour voir défini S4 méthodes est offert gentiment:

> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"

getMethod peut être utilisé pour voir le code source de l'une des méthodes:

> getMethod("chol2inv", "diagonalMatrix")
Method Definition:

function (x, ...) 
{
    chk.s(...)
    tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>

Signatures:
        x               
target  "diagonalMatrix"
defined "diagonalMatrix"

Il existe aussi des méthodes plus complexes signatures pour chaque méthode, par exemple

require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"

Pour voir le code source pour l'une de ces méthodes de la totalité de la signature doit être fourni, par exemple

getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )

Il ne suffira pas à fournir à la signature partielle

getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") : 
#  No method found for function "extract" and signature SpatialPolygons

Les fonctions appeler le code compilé

Notez que "compilé" ne fait pas référence à des octets compilé R code créé par le compilateur paquet. L' <bytecode: 0x294e410> ligne ci-dessus indique que la fonction est le byte-compilé, et vous pouvez toujours afficher la source à partir de la R de la ligne de commande.

Des fonctions qui appellent .C, .Call, .Fortran, .External, .Internalou .Primitive appelez les points d'entrée dans le code compilé, de sorte que vous aurez à regarder les sources du code compilé si vous voulez pleinement comprendre la fonction. Paquets peuvent utiliser .C, .Call, .Fortran, et .External; mais pas .Internal ou .Primitive, parce que ceux-ci sont utilisés pour appeler des fonctions intégrées dans le R de l'interprète.

Des appels à certaines des fonctions ci-dessus peuvent utiliser un objet au lieu d'une chaîne de caractère pour faire référence à la fonction compilée. Dans ces cas, l'objet est de classe "NativeSymbolInfo", "RegisteredNativeSymbol"ou "NativeSymbol"; et l'impression de l'objet produit de l'information utile. Par exemple, optim des appels .External2(C_optimhess, res$par, fn1, gr1, con) (à noter que l' C_optimhess, pas "C_optimhess"). optim est dans les stats de paquet, de sorte que vous pouvez taper stats:::C_optimhess voir les informations compilées fonction appelée.

Le code compilé dans un package

Si vous souhaitez afficher le code compilé dans un package, vous aurez besoin de télécharger/décompresser le package source. Installer les fichiers binaires ne sont pas suffisantes. Un code source du paquet est disponible à partir de la même CRAN (ou CRAN compatible) référentiel que le package a été installé à partir de. L' download.packages() fonction pouvez obtenir le paquet source pour vous.

download.packages(pkgs = "Matrix", 
                  destdir = ".",
                  type = "source")

Ceci va télécharger la version d'origine de la Matrice paquet et enregistrer la correspondante .tar.gz le fichier dans le répertoire courant. Code Source compilé les fonctions peuvent être trouvés dans l' src annuaire de la non compressé et untared fichier. La décompression et untaring étape peut être réalisée à l'extérieur de l' R, ou à partir de R à l'aide de l' untar() fonction. Il est possible de combiner le téléchargement et l'expansion de l'étape dans un seul appel (à noter que seule une offre à la fois peut être téléchargé et décompressé de cette façon):

untar(download.packages(pkgs = "Matrix",
                        destdir = ".",
                        type = "source")[,2])

Par ailleurs, si le développement de package est hébergé publiquement (par exemple via GitHub, R-Forge, ou RForge.net), vous pouvez probablement parcourir le code source en ligne.

Code compilé dans un package de base

Certains paquets sont considérés comme "de base" des paquets. Ces paquets navire avec R et leur version est verrouillé à la version de R. les Exemples incluent base, compiler, stats, et utils. En tant que tels, ils ne sont pas disponibles séparément les packs téléchargeables sur CRAN comme décrit ci-dessus. Au contraire, ils font partie de la R de la source de l'arbre dans l'emballage individuel sous-répertoires /src/library/. Comment accéder à la R source est décrite dans la section suivante.

Le code compilé construit dans la R interprète

Si vous souhaitez afficher le code intégré dans la R interprète, vous aurez besoin de télécharger/décompresser le R sources ou vous pouvez consulter les sources en ligne via le R le référentiel Subversion ou Winston Chang github miroir.

Uwe Ligges de R article de presse (PDF) (p. 43) est une bonne référence générale de la façon d'afficher le code source d' .Internal et .Primitive fonctions. Les étapes de base sont à la recherchent d'abord le nom de la fonction en src/main/names.c et ensuite, la recherche de la "C-entrée" nom du fichier src/main/*.

114voto

smci Points 2818

Outre les autres réponses sur cette question et ses doublons, voici un bon moyen pour obtenir le code source dans un fichier distinct, par exemple si nous voulons que la source de `` et ne sais pas qui c’est dans le paquet :

30voto

Selva Points 46

Il est révélé lors du débogage à l’aide de la fonction debug(). Supposons que vous souhaitez afficher le code sous-jacent dans t() transposer la fonction. Juste en tapant ' t ', ne révèle pas beaucoup.

Mais, à l’aide de la « debug(functionName) », elle révèle le code sous-jacent, sans les composants internes.

EDIT : debugonce() accomplit la même chose sans avoir à utiliser undebug()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X