I wrote a binary operator function for R (i.e. one with a name like %X%
so that instead of having to type %X%(a,b)
I can use the more convenient syntax a %X% b
. My goal is to have a wrapper for <-
that does things like log what was done to objects in that environment and check for a 'protected' attribute which would warn the user before overwriting that object.
All of this works, except that if I try do do something like a %X% b + c
inside the function all you see is a %X% b
_and that is also all it does; a gets assigned the value of b and c is completely ignored. a %X% (b + c)
works and so does %X%(a, b + c)
but the whole point of writing this as a binary operator is to avoid parentheses.
If I overwrite <-
, its sys.call()
sees everything to the left and right of it. Why does mine only see only the adjacent names from the command line?
Here is code that replicates this problem:
`%X%` <- function(...){
print(deparse(sys.call()));
}
a %X% 3 + 1:10;
The desired result is "a %X% 3 + 1:10" The observed result is "a %X% 3"
Thanks.
I suppose there is no way to lower the precedence of a custom operator. However, I think I found a cheesy workaround: I can name my operator
<<-
I don't really understand how
<-
dispatching works, and there must be dozens for different object-specific methods of<-
(none of which show up inmethods(
<-)
. All I know is that when I override<-
all kinds of stuff breaks.However,
<<-
has a precedence close to that of<-
, and it's not particularly useful because for the occasional case where you really do need to write a global variable from inside a function or a loop, you can just use.GlobalEnv[['foo']] <- bar
orassign('foo',bar,env=.GlobalEnv)
.Besides, since I'm only attempting to log and write-protect objects in .GlobalEnv in the first place, the new meaning I'm assigning to
<<-
is even somewhat consistent with the original one.This has to do with operator precedence, see
?Syntax
for more help. It says that special operators (%any%
) like the one you are trying to define have higher precedence than the binary+
, so there is no other way (AFAIK) for you than to use parenthesis and doa %X% (b + c)
.