On 8/22/12 11:04 PM, "Kasper Daniel Hansen" <kasperdanielhansen at gmail.com>
wrote:
>On Wed, Aug 22, 2012 at 4:47 PM, Steve Lianoglou <
>mailinglist.honeypot at gmail.com> wrote:
>
>> Hi,
>>
>> And since we're already getting pretty deep into the woods, I guess it
>> can't hurt to keep going:
>>
>> On Wed, Aug 22, 2012 at 4:11 PM, Kasper Daniel Hansen
>> <kasperdanielhansen at gmail.com> wrote:
>> > Martin has a great technical explanation.
>> >
>> > A briefer explanation is the following.
>> >
>> > 'We' used to use an initialize method to construct new objects, like
>> > new("ExpressionSet", exprs = MATRIX)
>> >
>> > This paradigm is used in a number of packages, including Biobase.
>> >
>> > 'We' later realized - for reasons Martin explains below - that this is
>> prone
>> > to failure and should not be used. However, you can still find tons
>>of
>> code
>> > using it - for legacy reasons.
>> >
>> > In general, you should not define the initialize method, you should
>>set a
>> > prototype when you define the class and you should write an explicit
>> > constructor, like
>> > ExpressionSet <- function() {}
>>
>> With the exception when your class has slots that are environments.
>>
>> If it's true that some things will still call new("YourClass", ...)
>> that aren't your constructor, then you will be surprised:
>>
>> setClass("A", representation=representation(cache="environment"),
>> prototype=prototype(cache=new.env()))
>> ctr <- function(cache=new.env()) new("A", cache=cache)
>>
>> ## This is the behavior you probably expect:
>> a = ctr()
>> b = ctr()
>> a at cache[['a']] = 1
>> b at cache[['a']]
>> NULL
>>
>> ## This isn't
>> y = new("A")
>> z = new("A")
>> y at cache[['a']] = 1
>> z at cache[['a']]
>> [1] 1 ## Woops!
>>
>>
>> But if you set an appropriate initialize method:
>>
>> setMethod(initialize, "A", function(.Object, ..., cache=new.env()) {
>> .Object at cache <- cache
>> callNextMethod(.Object, ...)
>> })
>>
>> All is well:
>> y = new("A")
>> z = new("A")
>> y at cache[['a']] = 1
>> z at cache[['a']]
>> NULL
>>
>
>This is of course true, but there are also the many reasons Martin
>outlined
>for why using the initialize method is not that great. I mean, of course
>there are advantages to the initialize method - this is after all why it
>was used and recommended for years in Bioconductor.
>
>If you use a class that has an explicit constructor, you should use that
>constructor, period. That you will mess up your objects by not doing
>that,
>ought to be self-evident. This is kind of the same as the fact that for
>for many classes it is possible to mess them up by directly assigning
>weird
>things to their slots (remember that validObject is not always called all
>the time, per default).
>
>Kasper
>
>
>
>>
>> I think ReferenceClasses replaces (most(?)) of the use cases that I
>> use the `cache` idiom for, although I'm not sure about the gotchas
>> with them because I haven't tried to grok RefClasses yet.
>>
>> Still ... thought I'd point this out (I think it was actually one of
>> you two, who must have alerted me to this years ago (perhaps on
>> R-devel)).
>>
>> -steve
>>
>> --
>> Steve Lianoglou
>> Graduate Student: Computational Systems Biology
>> | Memorial Sloan-Kettering Cancer Center
>> | Weill Medical College of Cornell University
>> Contact Info: http://cbio.mskcc.org/~lianos/contact
>>
>
> [[alternative HTML version deleted]]
>
>_______________________________________________
>Bioc-devel at r-project.org mailing list
>https://stat.ethz.ch/mailman/listinfo/bioc-devel