Dans R, j'utilise source()
pour charger certaines fonctions:
source("functions.R")
Est-il possible d'obtenir la liste de toutes les fonctions définies dans ce fichier? En tant que noms de fonction. (Peut source()
- être que lui - même peut le rendre en quelque sorte?).
PS: Le dernier recours serait d'appeler une source()
deuxième fois comme local({ source(); })
et ensuite de faire des fonctions ls()
internes et de filtrage, mais c'est trop compliqué - y a-t-il une solution plus facile et moins maladroite?
source()
, mais ce vieux fil peut vous intéresser.envir <- new.env() source("functions.R", local=envir) lsf.str(envir)
Réponses:
Je pense que la meilleure façon serait de placer le fichier dans un environnement temporaire. Recherchez cet environnement pour toutes les fonctions, puis copiez ces valeurs dans l'environnement parent.
la source
new.env()
au lieu de l'élégantlocal({ })
que je ne sais pas si cela fonctionnerait avec leassign
cadre parent.local()
? Et BTW, 2) ce que vous faites dans la boucle for: n'y a-t-il pas de fonction pour fusionner les environnements?attach
peut être utilisé pour, bien, attacher un environnement à un autre. Bien que vous deviez utiliser l'pos
argument plutôt que de spécifier leparent.frame
. Et cela ne fonctionnera bien que pour copier tout l'environnement, lafor
boucle de MrFlick vous permet de copier uniquement les fonctions.C'est un peu maladroit mais vous pouvez regarder les changements dans les objets avant et après l'
source
appel comme ça.la source
Je pense que cette expression régulière capture presque tous les types de fonctions valides (opérateur binaire, fonctions d'affectation) et tous les caractères valides dans un nom de fonction, mais j'ai peut-être manqué un cas de bord.
la source
.
et les fonctions d'assignation (`foo<-`<- function(x, value)
existent.=
pour l'affectation, cela n'attrapera aucune de mes fonctions ...` d d` <- function(x)
ce qui n'est actuellement pas pris. Je ne veux pas que l'expression régulière devienne trop idiote, bien que je puisse y revenir.assign
,<<-
et->
. Et il sera très difficile de faire en sorte que cette approche prenne en compte les fonctions définies dans les fonctions, mais qui ne se trouvent pas réellement dans l'environnement d'origine. Votre réponse devrait très bien fonctionner pour les cas standard, mais vous ne voulez pas réellement écrire un analyseur R hors regex.S'il s'agit de votre propre script afin que vous ayez le contrôle sur la façon dont il est formaté, une simple convention serait suffisante. Assurez-vous simplement que chaque nom de fonction commence au premier caractère de sa ligne et que le mot
function
apparaît également sur cette ligne. Toute autre utilisation du motfunction
doit apparaître sur une ligne commençant par un espace ou une tabulation. Ensuite, une solution en ligne est:Les avantages de cette approche sont que
c'est très simple . Les règles sont simplement énoncées et il n'y a qu'une seule ligne simple de code R nécessaire pour extraire les noms de fonction. Regex est également simple et pour un fichier existant, il est très facile à vérifier - il suffit de grep le mot
function
et de vérifier si chaque occurrence affichée suit la règle.pas besoin d'exécuter la source. C'est entièrement statique .
dans de nombreux cas, vous n'aurez pas du tout besoin de modifier le fichier source et dans d'autres, les modifications seront minimes. Si vous écrivez le script à partir de zéro dans cet esprit, il est encore plus facile à organiser.
Il existe de nombreuses autres alternatives à l'idée de conventions. vous pouvez avoir une expression rationnelle plus sophistiquée ou vous pouvez ajouter
# FUNCTION
à la fin de la première ligne de toute définition de fonction si vous écrivez le script à partir de zéro, puis repérez cette phrase et extrayez le premier mot de la ligne, mais la principale suggestion semble ici particulièrement attrayant en raison de sa simplicité et des autres avantages énumérés.Tester
la source
lapply(x, function(y) dostuff(y))
briserait cela# TODO
tout au long de mon code afin que je puisse exécuter mes tâches, par exemple. Une autre possibilité dans le même sens serait d'écrire# FUNCTION
à la fin de la première ligne de toute définition de fonction.Cela adapte le code utilisé dans la publication de mon commentaire pour rechercher une séquence de jetons (symbole, opérateur d'affectation, puis fonction), et il devrait saisir toutes les fonctions définies. Je ne sais pas si c'est robuste comme réponse de MrFlick, mais c'est une autre option:
la source