[R] How to change the value of a class slot

Ross Boylan ross at biostat.ucsf.edu
Tue Jun 7 20:58:09 CEST 2005


On Tue, 2005-06-07 at 08:36 +0200, Uwe Ligges wrote:
> Ross Boylan wrote:
> 
> > On Sat, Jun 04, 2005 at 07:08:56PM +0200, Martin Maechler wrote:
> > 
> >>    Ross> nextPath <- function(pm){ #pm is a CompletePathMaker
> >>    Ross>    pm at i <- pm at i+as.integer(1)
> >>    Ross> [etc]
> >>
> >>If your nextPath   function has  'pm' as its last statement it
> >>will return the updated object, and if you call it
> >>as
> >>	mypm <- nextPath(mypm)
> >>
> >>you are
> >>    1) updating  mypm
> >>    2) in a proper S way (i.e. no cheating).
> >>
> >>Regards,
> >>Martin
> > 
> > 
> > Wow.  This is almost the exact inverse of the usual object behavior,
> > in which only the class itself can update the slots (aka instance
> > variables).  None of the methods of the class can update instances of
> > the class persistently without the help of outsiders, and only
> > outsiders can change the slot values.
> > 
> > (Yes, I realize that using the idiom you suggest of returning a new
> > object one can have only class methods actually fiddling with the
> > slots.)
> > 
> > The inability of a class method to change a class object without
> > outside help seems unfortunate.
> > 
> > It looks as if instances of class objects are best thought of as
> > immutable once created.
> 
> Obviously, there are many definition of "object oriented" programming, 
> and yours seems to be different from the S4 definition.
Yes. And though there are many definitions of "object oriented" (at
least, many implementations),  I'd say the minimum requirement to be
object oriented is to have objects that encapsulate both state (instance
variables/slots) and behavior (methods).

S4 objects do not fully encapsulate state because they require outside
assistance to alter the state of the object (with the exception of
assignment operators).  The smalltalker in me also gets nervous that
code outside the class can access the slots, but there are many object
systems that act that way.

The way in which names of methods of unrelated classes interfere with
each other seems a break-down of the encapsulation of behavior, though
the problem strictly is not with the behavior but just with the name.
To return to the concrete problem that got me started, if class
Specification defines a method likelihood taking as arguments instances
of class Specification, Path and Parameters, then it is awkward to
define a method likelihood for the class Model when that method has
arguments of class Model, Specification, data.frame, and vector,
particularly if different names for the formal arguments are desired.
(I think technically it could be done, but only in a very ugly
way--i.e., better to use different method names for the two classes).

> 
> I was going to answer your first question at first, but you have not 
> given enough details - in particular it was not clear to me why your 
> approach did not work. 
> I assumed that you are assigning the new object 
> again, which is the S way. 
I wasn't, which is why it didn't work.  I wanted the function to return
some other value than the object it was operating on.
> You have to think about scoping rules and it 
> will be clear that the approach you are expecting is not a clean one in S.
Could you say a bit more about that?  I had thought of the issue more in
terms of function calls in S being call by value, preventing updates to
the original arguments.  So the issue isn't so much the scope of the
names of function arguments (that scope being limited to the function
body), but the properties of the thing they refer to (conceptually, a
copy of the argument, not the original).




More information about the R-help mailing list