简体   繁体   English

在函数内调用源-作用域问题

[英]Calling source within a function - scoping issue

I am trying to solve this scoping issue within function call. 我正在尝试解决函数调用中的此范围问题。 Function Perform throws an error. 函数Perform引发错误。 To be exact, error is Error in eval(expr, envir, enclos) : object 'a' not found . 确切地说,错误是Error in eval(expr, envir, enclos) : object 'a' not found Calling source within a function within another function is the issue (ie, object a is not available to CallScript function inside Perform function). 问题是在另一个函数内的函数内调用源(即,对象aPerform函数内的CallScript函数不可用)。 Perforxm1 is fine - so I want to understand how to fix Perform function. Perforxm1很好-所以我想了解如何修复Perform函数。 ( Add_a_b.R file is a script with just a+b for testing purposes). Add_a_b.R文件是仅用于测试目的的a+b脚本)。 Thanks in advance. 提前致谢。

CallScript<-function(ii){
  source(ii,echo = T,local=T)
}

Perform<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  CallScript(ii)
}

Perform1<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  source(ii,echo = T,local=T)
}

Perform(a=10,b=15)
Perform1(a=10,b=15)

I was playing with some options and found out a fix for the problem. 我正在使用一些选项,并找到了解决该问题的方法。 But I am still lacking the understanding. 但是我仍然缺乏理解。 So I am documenting my findings for different scenarios here. 因此,我在这里记录我针对不同场景的发现。 Hope this helps people! 希望这对人们有所帮助!

# To call within another function, reference enclosing environment!!
# Fixed my problem.
# Is there any other methods to achieve this?
CallScript<-function(ii){
  source(ii,echo = T, local=parent.frame())
}

Perform<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  CallScript(ii)
}

Perform(a=10,b=15)


# Using local=T or local=environment() options don't work in this scenario!
CallScript<-function(ii){
  source(ii,echo = T, local=T)
  #source(ii,echo = T, local=environment())
}    
Perform<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  CallScript(ii)
}    
Perform(a=10,b=15)


# I also found out that these also work.
Perform_env<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  source(ii,echo = T,local=environment())
}

Perform_loc<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  source(ii,echo = T,local=T)
}
Perform_env(a=10,b=15)
Perform_loc(a=10,b=15)


# But this doesn't work
Perform_par<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  source(ii,echo = T,local=parent.frame())
}
Perform_par(a=10,b=15)

To complicate things, here is another scenario. 使事情复杂化的是另一种情况。 Except local=F , all three options work in this scenario. 除了local=F以外,所有这三个选项在此情况下均有效。

# CallScript defined within `Perform` function.
Perform<-function(a,b){
  CallScript<-function(ii){
    # parent.frame works
    #source(ii,echo = T,local=parent.frame())

    # environment works
    #source(ii,echo = T,local=environment())

    # Local=T also work
    source(ii,echo = T,local=T)
  }

  ii<-'~/Test/Add_a_b.R'
  CallScript(ii)
}

Perform(a=10,b=15)

With @MrFlick's suggestion, this is also working: 在@MrFlick的建议下,这也有效:

CallScript<-function(ii){
  a <- get("a", parent.frame())
  b <- get("b", parent.frame())
  source(ii,echo = T, local=T)
}

Perform<-function(a,b){
  ii<-'~/Test/Add_a_b.R'
  CallScript(ii)
}

Perform(a=10,b=15)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM