2012-11-02 12 views
17

W kontynuacji mojej próby uniknięcia używania nawiasów dla prostych poleceń, napisałem następujący operator, aby utworzyć nowe okno graficzne. Moje pytanie brzmi: czy jestem narażony na ryzyko "zerwania" czegokolwiek w R, poza oczywistą niemożnością wykonania funkcji "not" na mojej zmiennej "newdev"?R Jednoargumentowe przeciążenie operatora: ryzyko?

# 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

Czy po prostu używałbyś tych prostych poleceń bezpośrednio w wierszu polecenia (tj. Nie osadzając ich w funkcjach lub czymś innym)? Jeśli tak, możesz utworzyć nową klasę i zdefiniować metodę drukowania dla tej klasy, która zrobiłaby to, co chcesz. – BenBarnes

+0

Myślę, że istnieje duża szansa, że ​​nazwałbym te polecenia wewnątrz funkcji, jeśli chcę utworzyć kolekcję wykresów, np. –

Odpowiedz

4

I wykonany "!" = function(a){stop("'NOT' is used")} i wykonywane funkcje replications, który wykorzystuje! operatora, a to działało dobrze. Wygląda więc na to, że można zignorować "!".

Nadal prawdopodobnie chcesz użyć klas, które można zrobić w następujący sposób:

# 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

Dobrze, choć nie zadziała to w moim zamierzonym celu, jakim było wykonanie określonego zamknięcia, które nie wymaga argumentu bez konieczności wpisywania "()" po nim. Jako przykład: '! Ls' zamiast' ls() '. I tak, jestem leniwy w ten sposób :-). (pamiętaj, domyślnym behaivorem w 'R' jeśli wpiszesz tylko nazwę zamknięcia jest wydrukowanie kodu zamknięcia do konsoli) –

+3

Aby dodać do tego: funkcje zdefiniowane interaktywnie lub w' '.Rprofile' idą w' globalenv () '- funkcje w pakietach nie mogą ich zobaczyć. Jednak wszelkie inne * funkcje *, które możesz mieć w swoim '.RProfile' będą miały wpływ. – Owen

1

z

makeActiveBinding 

można zastąpić ls() poprzez np LS w/o potrzebie operatorów jednoargumentowych

+0

To dobry punkt, a właściwie taki, którego używam do kilku "szybkich" funkcji. Właśnie skończyłem preferując opublikowaną metodę, ponieważ przepisałem ją za pomocą funkcji 'switch' - patrz kod źródłowy dla' splatnd' w pakiecie 'cgwtools'. –

Powiązane problemy