2015-03-27 6 views
10

Ho più funzioni che trattano argomenti che potrebbero mancare.R paradosso di valutazione lazy (R bug?)

ad es. Ho

mainfunction <- function(somearg) { 
    mytest(somearg) 
    fun <- function() { subfunction(somearg) } 
    fun() 
} 

con l'aspetto interessante che l'unica interazione mytest(somearg) con l'arg è che esso verifica se l'argomento non manca:

mytest = function(somearg) { 
    print(missing(somearg)) 
} 

subfunction quindi verifica nuovamente se non è presente e tratta di conseguenza:

subfunction = function(somearg) { 
    if (missing(somearg)) 
     somearg = NULL 
    else 
     somearg = matrix(somearg, cols = 2) 
    # somearg is used here… 
} 

il kicker è che, con somearg mancante, questo non funziona: matrix(somearg, cols = 2) tiri

argomento "somearg" manca, alcun valore predefinito

durante il debug, ho trovato il seguente:

  1. all'inizio del mainfunction, missing(somearg) rendimenti TRUE
  2. in mytest, missing(somearg) restituisce TRUE
  3. in subfunction, missing(somearg) rendimenti FALSE (!!!!)

quindi il ramo matrix è colpito, ma in realtà, someargè mancante, quindi non riesce ...

wat.

+1

Sto indovinando che il problema qui è che non si chiama direttamente "sottofunzione", ma piuttosto da una funzione annidata, che crea una chiusura sopra l'argomento 'somearg'. Sembra che le chiusure non possano trattare argomenti mancanti. Non sono sicuro che si tratti di un bug o di un "design": all'interno di "fun", "somearg" è ** non ** un argomento, è una variabile normale e quindi non può mancare. –

+6

Vedere la documentazione: "Attualmente' mancante 'può essere utilizzato solo nel corpo immediato della funzione che definisce l'argomento, non nel corpo di una funzione nidificata o di una chiamata 'local'." – Roland

+0

con "può essere utilizzato solo" che significa "si comporterà completamente inaspettato". Dannazione. Grazie. –

risposta

1

il modo @BenBolker:

mainfunction <- function(somearg = NULL) { 
    mytest(somearg) 
    fun <- function() { subfunction(somearg) } 
    fun() 
} 

mytest = function(somearg) { 
    print(is.null(somearg)) 
} 

subfunction = function(somearg) { 
    if (is.null(somearg)) 
     somearg = 1:10 
    else 
     somearg = matrix(somearg, ncol = 2) 
    somearg 
} 

Un altro modo, utilizzando esplicito argomento mancante

mainfunction <- function(somearg) { 
    is_missing <- missing(somearg) 
    mytest(is_missing) 
    fun <- function() { subfunction(somearg, is_missing) } 
    fun() 
} 
mytest = function(x) { print(x) } 
subfunction = function(somearg, is_arg_missing) { 
    if (is_arg_missing) 
     somearg = 1:10 
    else 
     somearg = matrix(somearg, ncol = 2) 
    somearg 
} 

Un terzo modo, utilizzando la lingua manca arg passaggio:

mainfunction <- function(somearg) { 
     is_missing <- missing(somearg) 
     mytest(somearg) 
     fun <- function() { 
      if (is_missing) subfunction() else 
       subfunction(somearg) 
     } 
     fun() 
    } 

    mytest = function(somearg) { 
     print(missing(somearg)) 
    } 

    subfunction = function(somearg) { 
     if (missing(somearg)) 
      somearg = 1:10 
     else 
      somearg = matrix(somearg, ncol = 2) 
     somearg 
    }