From luke at stat.uiowa.edu  Wed Jan 30 02:09:56 2008
From: luke at stat.uiowa.edu (Luke Tierney)
Date: Tue, 29 Jan 2008 19:09:56 -0600 (CST)
Subject: [Rd] Problem with new("externalptr")
In-Reply-To: <479FCCD6.3090700@fhcrc.org>
References: <479FB970.2060303@fhcrc.org> <479FCCD6.3090700@fhcrc.org>
Message-ID: <Pine.LNX.4.64.0801291906570.17475@localhost.localdomain>

On Tue, 29 Jan 2008, Herve Pages wrote:

> Hi again,
>
> Here is an example of an annoyance that I think is directly related to the
> problem with new("externalptr"). When you try to extend the "externalptr" class:

You don't wnat to do that for the same reason you don't want to do it
with environments: Like environment external pointers are reference
objects, so things like unclass and other attribute changes end up
being destructive.  Create the thing you want as a list wrapper around
the external pointer.  You'll be a lot happier with the result in the
long run.

luke


>
>  > setClass("ExternalInteger", contains="externalptr")
>  [1] "ExternalInteger"
>
> then every call to new("ExternalInteger") will return the same instance too.
>
> I've tried to define an "initialize" method for "ExternalInteger" objects, but,
> whatever I do, I end up with the same "ExternalInteger" instance. So in the end
> I had to define the "ExternalInteger" class this way:
>
>  > setClass("ExternalInteger", representation(xp="externalptr"))
>
> even if I'd really like to be able to use the "is a" semantic and not the "has a"
> semantic.
>
> Then I use my xp_new() C routine (see previous post) for initializing the xp slot:
>
>  setMethod("initialize", "ExternalInteger",
>    function(.Object, ...)
>    {
>        .Object at xp <- .Call("xp_new")
>        ...
>        .Object
>    }
>  )
>
> Then everytime I need to pass an "ExternalInteger" instance x to a C routine,
> I need to perform one extra step to reach the externalptr (need to pass x at xp to
> the routine instead of x itself).
>
> So unfortunately, things are quite ugly and more painful than necessary.
>
> Thanks,
> H.
>
>
> Herve Pages wrote:
>> Hi,
>>
>> It seems that new("externalptr") is always returning the same instance, and
>> not a new one as one would expect from a call to new(). Of course this is hard
>> to observe:
>>
>>  > new("externalptr")
>>   <pointer: (nil)>
>>  > new("externalptr")
>>   <pointer: (nil)>
>>
>> since not a lot of details are displayed.
>>
>> For example, it's easy to see that 2 consecutive calls to new("environment")
>> create different instances:
>>
>>  > new("environment")
>>   <environment: 0xc89d10>
>>  > new("environment")
>>   <environment: 0xc51248>
>>
>> But for new("externalptr"), I had to use the following C routine:
>>
>>   SEXP sexp_address(SEXP s)
>>   {
>>         SEXP ans;
>>         char buf[40];
>>
>>         snprintf(buf, sizeof(buf), "%p", s);
>>         PROTECT(ans = NEW_CHARACTER(1));
>>         SET_STRING_ELT(ans, 0, mkChar(buf));
>>         UNPROTECT(1);
>>         return ans;
>>   }
>>
>> Then I get:
>>
>>  > .Call("sexp_address", new("externalptr"))
>>   [1] "0xde2ce0"
>>  > .Call("sexp_address", new("externalptr"))
>>   [1] "0xde2ce0"
>>
>> Isn't that wrong?
>>
>> I worked around this problem by writing the following C routine:
>>
>>   SEXP xp_new()
>>   {
>>         return R_MakeExternalPtr(NULL, R_NilValue, R_NilValue);
>>   }
>>
>> so I can create new "externalptr" instances from R with:
>>
>>   .Call("xp_new")
>>
>> I understand that there is not much you can do from R with an "externalptr"
>> instance and that you will have to manipulate them at the C level anyway.
>> But since new("externalptr") exists and seems to work, wouldn't that be
>> better if it was really creating a new instance at each call?
>>
>> Thanks!
>> H.
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu



[Rd] Problem with new("externalptr")
Luke Tierney