2 votes

Est-il possible de faire en sorte que les fonctions reconnaissent les variables dans les scopes au-dessus d'elles ?

Je travaille en R, et je veux faire, par exemple,

printx <- function() {
  x <- 1
  printy()
  return(x)
}

printy <- function() {
  print(x)
}

parce que je ne veux pas continuer à faire circuler des tonnes de variables (de plus, il n'y a pas de x dans l'environnement global). Existe-t-il un moyen de faire cela ? Toutes les fonctions peuvent accéder à l'environnement global, mais qu'en est-il de celles qui se trouvent entre l'environnement de la fonction et l'environnement global ?

5voto

shhhhimhuntingrabbits Points 4970

Peut-être

printx <- function() {
  x <- 1
  printy()
  return(x)
}

printy <- function() {
  print(get('x',envir=parent.frame()))
}

> x<-0
> printy()
[1] 0
> printx()
[1] 1
[1] 1

Cela permettrait d'utiliser le x à imprimer par printy qui a été associé à l'environnement dans lequel la fonction a été appelée.

Une autre possibilité serait de créer un nouvel environnement

e1<-new.env(parent = baseenv())

> assign('x',12,envir=e1)
> x
[1] 0
> get('x',e1)
[1] 12

3voto

Michael Points 1466

Vous pourriez utiliser une fermeture pour obtenir des résultats similaires sans les risques associés aux risques évoqués ci-dessus. Sans savoir exactement ce que vous essayez de faire, il est difficile de présenter un exemple pertinent. Mais le code ci-dessous pourrait être intéressant...

create.functions <- function(x){
    list(
        function() x,
        function() x+1,
        function() x^2
    )

}

x <- 0

f1 <- create.functions(5)
f1[[1]]()
[1] 5
f1[[2]]()
[1] 6
f1[[3]]()
[1] 25

f2 <- create.functions(3)
f2[[1]]()
[1] 3
f2[[2]]()
[1] 4
f2[[3]]()
[1] 9

x
[1] 0

Remarquez que vous pouvez créer une suite de fonctions partageant le même paramètre, x, sans qu'il y ait de conflit entre le paramètre x et la valeur de x dans l'environnement global. Si vous avez besoin d'un nouvel ensemble de fonctions où le paramètre x est défini différemment, vous pouvez simplement créer un nouvel ensemble.

On pourrait même faire en sorte que le code s'appuyant sur la suite de fonctions ne doive pas être modifié lors du changement de la valeur de votre paramètre :

f <- create.functions(5)
f[[1]]()/f[[3]]()
[1] 0.2

f <- create.functions(3)
f[[1]]()/f[[3]]()
[1] 0.3333333

Notez que la même ligne de code f[[1]]()/f[[3]]() renvoie des résultats différents selon la façon dont le paramètre x a été défini.

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