From rgentlem at fhcrc.org  Wed Jan 30 06:32:54 2008
From: rgentlem at fhcrc.org (Robert Gentleman)
Date: Tue, 29 Jan 2008 21:32:54 -0800
Subject: [Rd] Problem with new("externalptr")
In-Reply-To: <479FB970.2060303@fhcrc.org>
References: <479FB970.2060303@fhcrc.org>
Message-ID: <47A00C06.4080706@fhcrc.org>

Hi,

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>

   getMethod("initialize", "environment")
and

   getMethod("initialize", "externalptr")

  will give some hints about the difference.
> 
> 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?

   Not what you want, but not wrong. In the absence of an initialize 
method all calls to "new" are guaranteed to return the prototype; so I 
think it behaves as documented.

   new("environment") would also always return the same environment, 
were it not for the initialize method.  So you might want to contribute 
an initialize method for externalptr, but as you said, they are not 
useful at the R level so I don't know just what problem is being solved.

   This piece of code might be useful in such a construction
.Call("R_externalptr_prototype_object", PACKAGE = "methods")

  which does what you would like.

  best wishes
    Robert

> 
> 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
> 

-- 
Robert Gentleman, PhD
Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M2-B876
PO Box 19024
Seattle, Washington 98109-1024
206-667-7700
rgentlem at fhcrc.org



[Rd] Problem with new("externalptr")
Robert Gentleman