2010-07-18 41 views
10

Tôi đang cố gắng viết một hàm, giới hạn phạm vi của các biến R. Ví dụ:Giới hạn phạm vi biến

source("LimitScope.R") 
y = 0 
f = function(){ 
    #Raises an error as y is a global variable 
    x = y 
} 

Tôi nghĩ thử nghiệm môi trường biến, nhưng không thực sự chắc chắn về cách thực hiện điều này.

tại sao

tôi dạy R để undergrads. Trong vài thực hành đầu tiên của họ, một vài trong số họ luôn quên đi phạm vi thay đổi, vì vậy các chức năng được gửi của họ không hoạt động. Ví dụ: tôi luôn nhận được một cái gì đó như:

n = 10 
f = function(x){ 
    #Raises an error 
    #as I just source f and test it for a few test cases. 
    return(x*n) 
} 

Tôi đã theo sau một chức năng nhanh chóng có thể 'tắt' phạm vi. Như bạn có thể tưởng tượng nó không phải là đặc biệt mạnh mẽ, vì nó sẽ chỉ được cung cấp cho một vài thực tế.

+0

Không quan tâm, tại sao bạn muốn thực hiện việc này? –

+0

Tôi đã thêm một phần trong câu trả lời về lý do tại sao tôi muốn làm điều này. – csgillespie

+0

Xem thêm http://stackoverflow.com/questions/6216968/r-force-local-scope –

Trả lời

4

Tôi không chắc chắn rằng bạn muốn thực hiện điều này nói chung, nhưng chức năng local() sẽ hữu ích, như thư viện codetools.

Trong ví dụ của bạn, hãy thử

f = local(function() { ... }, baseenv()) 

Nó không thực hiện chính xác những gì bạn muốn, nhưng nó sẽ giúp bạn gần gũi hơn.

1

Bạn có thể kiểm tra nếu y tồn tại trong môi trường toàn cầu sử dụng exists('y',envir=.GlobalEnv)

3

Bạn có thể buộc một biến là phiên bản địa phương với chức năng này:

get_local <- function(variable) 
{ 
    get(variable, envir = parent.frame(), inherits = FALSE) 
} 

Hãy so sánh những trường hợp này

y <- 0  
f <- function() 
{ 
    x <- y 
}  
print(f())  # 0 

y <- 0  
f <- function() 
{ 
    y <- get_local("y") 
    x <- y 
}  
print(f())  # Error: 'y' not found 

Tùy thuộc vào những gì bạn đang làm, bạn cũng có thể kiểm tra xem nếu y là một đối số cho f , sử dụng formalArgs hoặc formals.

g <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0 

formalArgs(g) 
# [1] "x" "y" "z" "..." 

formals(g) 
#$x 
# 
# 
#$y 
#[1] TRUE 
# 
#$z 
#c("foo", "bar") 
# 
#$... 

EDIT: Điểm chung hơn về cách tắt phạm vi từ vựng mà không thay đổi nội dung chức năng khó giải quyết hơn. Tôi khá chắc chắn rằng các quy tắc phạm vi khá ăn sâu vào R. Một thay thế có thể là sử dụng S-Plus, vì nó có different scoping rules.

0

Điều gì xảy ra với tôi là tôi có màn hình chia nhỏ trong ESS với bộ đệm tệp mã R ở bên trái và trình thông dịch ở bên phải. Tôi có thể đã đặt một số giá trị trong trình thông dịch trong khi tôi gỡ lỗi mã mà tôi đang làm việc trong bộ đệm. Đó là sau đó có thể là mã trong bộ đệm vô tình refereneces một cái gì đó tôi đặt trong intepreter. Đó là khó khăn để phát hiện vấn đề, trừ khi tôi đánh giá bộ đệm của tôi trong một thông dịch viên tươi mỗi lần, đó không phải là cách ESS hoạt động theo mặc định.

Nếu đây là loại vấn đề bạn thường thấy, một rm (list = ls (envir = .GlobalEnv)) trong điều bạn nguồn có thể giúp, nhưng tất nhiên tạo ra các vấn đề khác, chẳng hạn như xóa bất cứ thứ gì chúng đang sử dụng để giữ trạng thái khi đang gỡ lỗi, v.v.

Các vấn đề liên quan