From mtmorgan at fhcrc.org  Tue Nov  1 14:37:07 2011
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Tue, 01 Nov 2011 06:37:07 -0700
Subject: [Rd] Question about copying reference objects using the
 initialize method
In-Reply-To: <CAGnmr57=uxTf+7POZ6=gOOuu5h4RmLJ_4VD1SvuhR1NtAaXuFQ@mail.gmail.com>
References: <CAGnmr57=uxTf+7POZ6=gOOuu5h4RmLJ_4VD1SvuhR1NtAaXuFQ@mail.gmail.com>
Message-ID: <4EAFF603.80902@fhcrc.org>

On 10/31/2011 08:53 AM, Aleix Ruiz de Villa wrote:
> Dears,
>
> I have a question about copying reference objects using the initialize method.
>
> 1) If the latter has no arguments, there is no problem to copy an object.
>
> myClass = setRefClass("myClass", fields = list(value = "numeric") )
>
> myClass$methods(initialize = function(...){
>
>    value<<- 1
>
>    callSuper(...)
> })
>
> newObject = myClass$new()
> newObject$value = 2
> copyObject = newObject$copy()
> copyObject$value = 3
> print(newObject$value)
> print(copyObject$value)
>
>
> 2) However, if the initialize method has arguments, I get an error:
>
> myClass = setRefClass("myClass", fields = list(value = "numeric") )
> myClass$methods(initialize = function(extValue, ...){
>
>    value<<- extValue
>
>    callSuper(...)
> })
> newObject = myClass$new(extValue = 2)
> copyObject = newObject$copy()
>
> Error in .Object$initialize(...) :
>    argument "extValue" is missing, with no default
>
>
> I understand that copy() first builds another instance of the object
> and then copies the fields. But it calls new without arguments...
>
> 3) One solution would be the initialize values by default
>
> myClass = setRefClass("myClass", fields = list(value = "numeric") )
>
> myClass$methods(initialize = function(extValue = 1, ...){
>
>    value<<- extValue
>
>    callSuper(...)
> })
>
> newObject = myClass$new(extValue = 2)
> copyObject = newObject$copy()
>
>
> But I have a long list of arguments, so this way would be a little
> uncomfortable. On the other hand, I've been told that in OOP, the idea
> of the initialise method is to use the minimum information to build
> the oject. So passing a long list of arguments is not a good idea.
>
>
> 4) Another option is to first build the object and then set the parameters
>
> myClass = setRefClass("myClass", fields = list(value = "numeric") )
>
> myClass$methods(setPar = function(extValue = 1, ...){
>
>    value<<- extValue
>
>    return()
> })
>
> newObject = myClass$new()
> newObject$setPar(extValue = 2)
> copyObject = newObject$copy()
>
>
> It works fine.
>
> Anyway I am curious to know if there is any way to use the initialize
> method with arguments that is not a problem with copy().

Hi Aleix --

 From ?setRefClass

           Initialization methods
           need some care in design, as they do for S4 classes. In
           particular, remember that others may subclass your class and
           pass through field assignments or other arguments.
           Therefore, your method should normally include ... as an
           argument, all other arguments should have defaults or check
           for missingness, and your method should pass all initialized
           values on via '$callSuper()' or '$initFields()' if you know
           that your superclasses have no initialization methods.

so it sounds like your initialize method arguments are expected to have 
default values. My preferred signature would place the '...' first, so 
that unnamed arguments (super-classes) are not unintentionally matched 
to named arguments.

Martin

>
>
> Thank!
>
> Aleix Ruiz de Villa
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



[Rd] Question about copying reference objects using the initialize method
Martin Morgan