Accéder à l'environnement précédent via une fonction

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Bastien Gamboa
Messages : 151
Enregistré le : 13 Jan 2011, 21:31

Accéder à l'environnement précédent via une fonction

Messagepar Bastien Gamboa » 03 Oct 2017, 12:37

Bonjour,

Lors de l'évaluation d'une fonction, je souhaite avoir accès aux objets de l'environnement précédent.

Un exemple pour tenter d'être plus explicite :

Code : Tout sélectionner

fun1 <- function(x) eval(parse(text=x))
fun2 <- function() {
  aaa <- 1
  fun1("ls(envir=environment(fun2))")
}
bbb <- c(2, "BlaBla")
fun2() # [1] "bbb"  "fun1" "fun2"
Dans cet exemple, je pensais que fun2() renverrait aaa, ce que je voulais d'ailleurs. Mais après avoir essayer environment(), parent.frame(), sys.function(), et plein d'autres je ne parviens pas à accéder aux objets accessibles par fun2() via l'appel de fun1().

Avez-vous une idée comment faire (si bien sûr c'est assez clair) ?

Merci,
Bastien

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Accéder à l'environnement précédent via une fonction

Messagepar Pierre-Yves Berrard » 03 Oct 2017, 12:52

Bonjour,
Le problème ne viendrait-il pas que environment(fun2) renvoie l'environnement dans lequel fun2 a été créé, à savoir l'environnement global ?
PY

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Accéder à l'environnement précédent via une fonction

Messagepar Pierre-Yves Berrard » 03 Oct 2017, 13:14

Par tâtonnement, en changeant l'environnement dans l'appel de ls() :

Code : Tout sélectionner

fun1 <- function(x) eval(parse(text=x)) 
fun2 <- function() {
  aaa <- 1
  list(
    n1 = fun1("ls(envir = parent.frame())"),
    n2 = fun1("ls(envir = parent.frame(2))"),
    n3 = fun1("ls(envir = parent.frame(3))"),
    n4 = fun1("ls(envir = parent.frame(4))")
  )
}
bbb <- c(2, "BlaBla")
                                         
fun2()                                   
#> $n1
#> [1] "enclos" "envir" "expr"
#> $n2
#> [1] "x"
#> $n3
#> [1] "aaa"
#> $n4
#> [1] "bbb" "fun1" "fun2"

À noter que je ne comprends que vaguement pourquoi il faut prendre n = 3...
PY

Bastien Gamboa
Messages : 151
Enregistré le : 13 Jan 2011, 21:31

Re: Accéder à l'environnement précédent via une fonction

Messagepar Bastien Gamboa » 04 Oct 2017, 09:59

Bonjour,

Merci Pierre-Yves de t'intéresser à mon problème. Ta solution fonctionne dans le 1er exemple, mais il s'avère qu'il était trop simplifié pour illustrer mon problème.
Avec ce nouvel exemple, ta solution ne fonctionne plus (PI je suis allé jusqu'à n=10 et pas de changements).
As-tu d'autres idées ?
Pour rappel, mon objectif et de voir aaa via l'appel de fun1() quand je lance fun2()

Code : Tout sélectionner

require(tcltk)
fun1 <- function()
  print(list(
    n1 = ls(envir = parent.frame(1)),
    n2 = ls(envir = parent.frame(2)),
    n3 = ls(envir = parent.frame(3))
  ))
fun2 <- function() {
  aaa <- 1
  tt <- tktoplevel()
  tkpack(tkbutton(tt, text="launch", command=fun1))
}
bbb <- c(2, "BlaBla")
fun2()

Merci,
Bastien

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Accéder à l'environnement précédent via une fonction

Messagepar Logez Maxime » 04 Oct 2017, 11:36

Bonjour,

Une solution est de spécifier dans fun2 l'environnement de fun1:

Code : Tout sélectionner

require(tcltk)
fun1 <- function() {
  l1 <- ls(envir = env1)
  l1 <- l1[!l1 %in% c("env1", "tt", "fun1")]
  print(list(l1))
  }
fun2 <- function() {
  aaa <- 1
  env1 <- environment()
  tt <- tktoplevel()
  environment(fun1) <- env1
  tkpack(tkbutton(tt, text="launch", command=fun1))
}
bbb <- c(2, "BlaBla")
fun2()
[[1]]
[1] "aaa"
Cordialement,
Maxime

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Accéder à l'environnement précédent via une fonction

Messagepar Logez Maxime » 04 Oct 2017, 19:54

Bonjour,

une autre possibilité (que j'aime moins) est d'arriver à faire passer env1 à la fonction fun1, soit en sauvant env1 dans l'environnement global, soit en le stockant dans un environnement connu des deux fonctions :

Code : Tout sélectionner

require(tcltk)
fun1 <- function() {
  l1 <- ls(envir = env1)
  l1 <- l1[!l1 %in% c("env1", "tt", "fun1")]
  print(list(l1))
  }
fun2 <- function() {
  aaa <- 1
  env1 <<- environment()
  tt <- tktoplevel()
  tkpack(tkbutton(tt, text="launch", command=fun1))
}
bbb <- c(2, "BlaBla")
fun2()
Cordialement,
Maxime


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité