On 04.06.2011, at 15:41, Martin Morgan wrote:

> On 06/04/2011 03:07 AM, soeren.vo...@uzh.ch wrote:
> 
>> Hello, an S4 class "Foo" is defined with a setter, $. For several reasons, 
>> the setter calls a function, .foo.update(). However, bypassing the argument 
>> names of the setter does not work. Question 1: Why not and how can I fix 
>> this? Question 2: What is the way to define either the function or the 
>> setter to modify the original object (not returning the modified copy of it 
>> an overwrite the original by assignment)? Thanks, Sören
>> 
>> setClass("Foo",
>>   representation(
>>     N = "numeric"
>>   ),
>>   prototype(
>>     N = 10000
>>   )
>> )
>> 
>> .foo.update<- function(object, ...) {
>>   args<- list(...)
>>   for (i in slotNames("Foo")[pmatch(names(args), slotNames("Foo"), 
>> nomatch=0)]) {
>>     slot(object, i)<- args[[i]]
>>     # indeed more to do here
>>     return(object)
>>   }
>> }
> 
> Since names(args) is 'name', and 'name' is not a slot of 'Foo', the return of 
> pmatch is 0 and .foo.update returns NULL. Put return(object) outside the for 
> loop.
> 
>> setReplaceMethod("$", "Foo",
>>   function(x, name, value) {
>>     x<- .foo.update(x, name=value)
>>     x
>>   }
>> )
>> 
>> x<- new("Foo")
>> x
>> x$N<- 99
>> x # NULL????
> 
> here your intention is that name=value to be substituted with N=99, but you 
> end up with name=99. You could arrange to parse this correctly, but this 
> isn't usually what you _want_ to do and I don't really understand what you're 
> trying to accomplish.

Exactly, what I want to parse is "N"=99. To clarify, .foo.update should be the 
"one" workhorse to do a couple of things depending on arguments on more than 
one object (see my post on interfacing a C++ class, just some minutes ago). 
Thus, assigning x@N = 10 (x$N, x["N"]) should not only end up in x (object of 
class Foo) with value 10, but also should invoke FOO$setN(10) (a setter for the 
C++ object, not shown here). So far, .foo.update works perfectly and indeed 
alters the object x, but the setter does not parse the argument name. I tried 
with quote, substitute, deparse ..., but got none working ...

> Maybe
> 
> .foo.update <- function(object, name, value, ...)
> {
>    slot(object, name) <- value
>    ## some other stuff
>    object
> }
> 
> Hope that helps a bit.
> 
> Martin

Thanks, Sören

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to