I am a big fan of S4 Reference Classes, as they allow a hybrid programming style (functional / pass-by-value versus oop / pass-by-reference, example ) and thus greatly increase flexibility.
However, I think I just came across undesirable behavior regarding the method of scanning R through environments / frames when you ask it to get a specific field value using the $field() method (see the man page ). The problem is that R also seems to look in environments / frames if the desired field is not found in the real local / target environment (which would be the environment making up the S4 reference class), i.e. it just ran get(<objname>, inherits=TRUE) (see the man page ).
Actual question
To make R just look in the local / target environment, I thought of something like $field(name="<fieldname>", inherits=FALSE) , but $field() has no argument ... that would let me go through inherits=FALSE to get() (which I assume is called somewhere along the way). Is there any way around this?
Code example
For those who are interested in more detailed information: here is a small sample code illustrating the behavior
setRefClass("A", fields=list(a="character")) x <- getRefClass("A")$new(a="a")
Class A has field A , so it is in the target environment and the value is returned:
> x$field("a") [1] "a"
Everything looks different if we try to access a field that is not a field of the reference class, but has a name identical to the name of some other object in the workspace / search path (in this case "lm" ):
require("MASS") > x$field("lm") function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, ...) { ret.x <- x ret.y <- y [omitted] if (!qr) z$qr <- NULL z } <bytecode: 0x02e6b654> <environment: namespace:stats>
In fact, I did not expect this. IMHO a mistake or at least a warning would be much better. Or the opening method of $field() for arguments that can be passed along with other functions via ... I assume that somewhere along the path get() is called when $field() called, so something like this might interfere with the behavior described above:
x$field("digest", inherits=FALSE)
Workaround: Own Proposal
This should do the trick, but maybe there is something more elegant that is not related to the specification of the new method on top of $field() :
setRefClass("A", fields=list(a="character"), methods=list( myField=function(name, ...) {