2012-11-02 43 views
17

爲了避免對一些簡單的命令使用圓括號,我寫了下面的操作符來創建一個新的圖形窗口。我的問題是:除了明顯無法在變量「newdev」上執行「not」函數之外,我是否有可能「破壞」R中的任何內容?R一元運營商過載:風險?

# function to overload "!" for one purpose only 
#this is adapted from the sos package code for "???", credited to Duncan Murdoch. 
# Example of how to create a specialized unary operator that doesn't require 
# parentheses for its argument. So far as I can tell, 
#the only way to do this is to overload an existing function or 
# operator which doesn't require parentheses. "?" and "!" meet this requirement. 
`!` <- function (e1, e2) { 
call <- match.call() 
# match.call breaks out each callable function in argument list (which was "??foo" for the sos package "???", 
# which allows topicExpr1 to become a list variable w/ callable function "!" (or "?" in sos) 
original <- function() { 
    call[[1]]<-quote(base::`!`) 
    return(eval(call, parent.frame(2))) 
} 

    # this does preclude my ever having an actual 
    # variable called "newdev" (or at least trying to create the actual NOT of it) 
if(call[[2]] =='newdev') { 
    windows(4.5,4.5,restoreConsole=T) 
}else{ 
    return(original()) # do what "!" is supposed to do 
} 
} 
+0

你會直接在命令提示符下使用這些簡單的命令嗎(即不是將它們嵌入函數或什麼)?如果是這樣,您可以創建一個新類併爲該類定義一個打印方法,以實現您想要的效果。 – BenBarnes

+0

我認爲如果我想要創建一個圖表集合,例如在函數內調用這些命令的機會很大, –

回答

4

我執行"!" = function(a){stop("'NOT' is used")}和執行replications功能,它使用了!運營商,這工作得很好。因此,重寫「!」似乎是安全的。

不過你可能想使用類,你可以做如下:

# Create your object and set the class 
A = 42 
class(A) = c("my_class") 

# override ! for my_class 
"!.my_class" = function(v){ 
    cat("Do wathever you want here. Argument =",v,"\n") 
} 

# Test ! on A 
!A 
+0

好的一點,雖然這不會用於我的預期目的,即執行特定的閉包,不需要參數而不必在其後輸入「()」。例如,'!ls'而不是'ls()'。而且,是的,我很懶惰:-)。 (請記住,如果僅輸入閉包的名稱,則在'R'中的默認行爲是將閉包代碼打印到控制檯) –

+3

要添加到:以交互方式或在'.Rprofile'中定義的函數在'globalenv )' - 包中的函數看不到它們。但是,'.RProfile'中可能存在的其他任何*函數都將受到影響。 – Owen

1

makeActiveBinding 

可以取代LS()​​由如LS W/O需要一元運算符

+0

這是一個很好的觀點,實際上我使用了一些「快速」功能。我只是最終選擇了發佈的方法,因爲我使用'switch'函數重寫了它 - 在包'cgwtools'中查看'splatnd'的源代碼。 –