views:

105

answers:

1

OK, so I'm trying to use S4 classes to build a very complex object, with slots including a half-dozen matrices, a few lists, and probably a kitchen sink or two in there. The object is initialized by referring to and unpacking a configuration object which I've already defined. It's easy enough to define the class with setClass(), but I'm having difficulty figuring out an elegant way of setting the slots in the setMethod("initialize").

The problem is that I need to set particular elements of those half-dozen matrices based on parts of that configuration object. For each element of the configuration object, I may have to set specific elements of several of the matrices. Note that the matrices are in the scope/environment of the initialize function. I then have nested functions within the initialize function that do the actual assignment to the matrices, or that's the idea anyway. Those functions can of course see the matrices, but they can't modify them because the <- operator creates a new matrix if the original variable was not defined in the current environment. R is pass-by-value, and means it. This is even true for slots of the .Object I'm trying to initialize. So I can't use nested functions to do the initialization.

Unfortunately, these nested functions have to modify several of the matrices, so returning values and doing the assignment in the main initialize function is not practical or elegant. (But it is possible, if I stuffed copies of the matrices into returned lists and then combined them in the main initialize function. Ugly though, and would require a lot of extra code.)

And iteration (which would prevent this scoping issue) is not very practical either because of the hierarchical nature of the configuration object, which really wants to be traversed with recursive calls.

The last option I can think of would be to use the assign() function with the envir option to force the assignment to apply to the nonlocal variable. But using environments like that seems icky, like a goto statement...

So, what is the most piratical approach? Stick with pure functional programming and build ugly data structures just to inefficiently pass around redundant matrices? Try to find an iterative solution that avoids functions altogether? Use deep magic by playing with environments?

+1  A: 

Have you looked at <<- ? It makes assigning in the parent environment a little easier.

hadley
Ah, yes, overlooked that, and doesn't have the same "cop-out" feeling as assign() with an explicit specification of the environment!
Harlan