Re: [Rd] Problem with new("externalptr")

2008-01-29 Thread Robert Gentleman
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")
>   
>   > new("externalptr")
>   
> 
> 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")
>   
>   > new("environment")
>   

   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@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
[EMAIL PROTECTED]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Problem with new("externalptr")

2008-01-29 Thread Herve Pages
Luke Tierney wrote:
> 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.

Thanks Luke!

As you've probably seen further below in my post, wrapping instead of extending
is indeed what I'm doing. And I'm explaining why I don't really have the choice
right now.
I understand why, generally speaking, you would recommend wrapping instead of
extending, but, given the context where I'm making use of those external 
pointers
(the "ExternalInteger" class itself is not exported, only used internally as 
slots
of higher level objects, never accessed directly, etc..., etc...), I don't think
extending would actually be a problem.

Unfortunately, because of the problem with new("externalptr"), I can't even
experiment the "extending" approach, test it, compare it with the "wrapping"
approach, etc... and make my own opinion.
And even if I stick with the "wrapping" approach, it would help to have
new("externalptr") doing what I think is the right thing to do.

Cheers,
H.


> 
> 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, ...)
>>{
>>[EMAIL PROTECTED] <- .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 [EMAIL PROTECTED] 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")
>>>   
>>>  > new("externalptr")
>>>   
>>>
>>> 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")
>>>   
>>>  > new("environment")
>>>   
>>>
>>> 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@r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
>> __
>> R-devel@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Problem with new("externalptr")

2008-01-29 Thread Luke Tierney
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, ...)
>{
>[EMAIL PROTECTED] <- .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 
> [EMAIL PROTECTED] 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")
>>   
>>  > new("externalptr")
>>   
>>
>> 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")
>>   
>>  > new("environment")
>>   
>>
>> 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@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> __
> R-devel@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 andFax:   319-335-3017
Actuarial Science
241 Schaeffer Hall  email:  [EMAIL PROTECTED]
Iowa City, IA 52242 WWW:  http://www.stat.uiowa.edu

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Problem with new("externalptr")

2008-01-29 Thread Herve Pages
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:

  > 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, ...)
{
[EMAIL PROTECTED] <- .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 [EMAIL 
PROTECTED] 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")
>   
>   > new("externalptr")
>   
> 
> 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")
>   
>   > new("environment")
>   
> 
> 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@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Problem with new("externalptr")

2008-01-29 Thread Herve Pages
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")
  
  > new("externalptr")
  

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")
  
  > new("environment")
  

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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel