2016-10-21 2 views
3

match.call을 사용하는 함수를 작성했지만 직접 함수를 호출 할 때 작동하지만 다른 함수 내에서 함수가 호출 될 때 작동합니다. 나는 그것이 환경을 처리하는 방법과 관련이 있다고 믿는다. 그러나 나는 그것을 이해할 수 없다. 여기에 재현 할 예입니다match.call과 관련된 문제

tester <- function() { 

    var <- "helloworld" 

    myFunc(var) 

} 


myFunc <- function(x) { 

    tmp <- match.call() 
    tmp[[1]] <- quote(toupper) 
    eval(tmp) 

} 

tester() # error 

myFunc("helloworld") # works fine 

내가 myFunctester 내에서 호출되는 경우는 tester 함수의 격리 된 환경에 존재하기 때문에이 var을 찾을 수 있다고 생각합니다.

myFunctester 내부에서 작업하는 방법에 대한 아이디어가 있으면 알려 주시면 감사하겠습니다. evalmatch.call에 대한 환경을 변경하려고했지만 아무 소용이 없습니다.

답변

5

의심의 여지가 있습니다.

매우 간단한 해결책은 부모의 컨텍스트에서 함수를 평가하는 것입니다. evaleval.parent으로 바꿉니다.

myFunc <- function(x) { 
    tmp <- match.call() 
    tmp[[1]] <- quote(toupper) 
    eval.parent(tmp) 
} 

일반적으로, 기능 traceback 디버깅 유사한 문제에 엄청난 도움이 될 수 있습니다

> tester() 
Error in as.character(x) : 
    cannot coerce type 'closure' to vector of type 'character' 

좋아하지만, 어떤 "폐쇄"(= 기능) 우리는 얘기?

> traceback() 
5: toupper(x = var) 
4: eval(expr, envir, enclos) 
3: eval(tmp) at #5 
2: myFunc(var) at #5 
1: tester() 

첫 번째 줄의 단서는 toupper(x = var)입니다. tester의 문맥에서, var은 패키지가 첨부되어 있기 때문에 발견 된 기능 (폐쇄) stats::var을 나타냅니다.

+0

아, 'eval'의 환경을 변경하는 것도 효과가 있습니다. 실제로, 그것은 정확히'eval.parent'가하는 것입니다; 이것은'eval (tmp, envir = parent.frame())'과 동일합니다. 어쨌든 이것이'eval' 매개 변수'envir'의 디폴트 값이라는 사실에 그릇된 생각을하지 마십시오. 인수 값을 지정하고 그것의 기본값을 사용하면 매개 변수 기본값이 함수 내부에서 평가되기 때문에 다른 값을 생성 할 수 있습니다 함수에 전달하면 함수 밖에서 평가됩니다. 이것은 매우 혼란 스럽다. –

+0

기술적으로,'eval (tmp, envir = parent.frame (2))'과 동등합니다. 나는 맹세 했었지만, 고마워요. – Carl

+0

아, 제 의견이 보이네요. – Carl