From murdoch at stats.uwo.ca  Thu Oct  1 18:53:22 2009
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Thu, 01 Oct 2009 12:53:22 -0400
Subject: [Rd] creating environments in package's C code
In-Reply-To: <4AC4DAC8.6010107@vanderbilt.edu>
References: <4AC4CBD9.7010309@mx.uni-saarland.de>	<4AC4D3C5.7090609@vanderbilt.edu>
	<4AC4DAC8.6010107@vanderbilt.edu>
Message-ID: <4AC4DE82.1060908@stats.uwo.ca>

On 10/1/2009 12:37 PM, Jeff Horner wrote:
> Jeff Horner wrote:
>> Martin Becker wrote:
>>> Dear developers,
>>>
>>> is it possible to create environments in C code of packages?
>>> Simply using
>>>  SEXP env;
>>>  PROTECT (env  = allocSExp(ENVSXP));
>>> and assigning the enclosing environment with SET_ENCLOS seems to be 
>>> insufficient.
>>>
>>> Best wishes,
>> 
>> Here's a function I use in rapache to create one:
>> 
>> static SEXP NewEnv(SEXP enclos){
>>     SEXP env;
>>     PROTECT(env = allocSExp(ENVSXP));
>> 
>>     SET_FRAME(env, R_NilValue);
>>     SET_ENCLOS(env, (enclos)? enclos: R_GlobalEnv);
>>     SET_HASHTAB(env, R_NilValue);
>>     SET_ATTRIB(env, R_NilValue);
>> 
>>     UNPROTECT(1);
>> 
>>     return env;
>> }
> 
> Oops! I forgot the definition of my simple function NewInteger:
> 
> static SEXP NewInteger(int i){
>      SEXP val;
>      PROTECT(val = NEW_INTEGER(1));
>      INTEGER_DATA(val)[0] = i;
>      UNPROTECT(1);
>      return val;
> }
> 
>> 
>> 
>> and an example that creates a new environment and then assigns a 
>> variable named OK an integer vector length 1 with value 0:
>> 
>> SEXP env = NewEnv(R_GlobalEnv);
>> defineVar(install("OK"),NewInteger(0),env);


One comment:  I would protect the env, because install() and 
NewInteger() could each trigger a garbage collection.  That is, use

SEXP env;
PROTECT(env = NewEnv(R_GlobalEnv));
defineVar(install("OK"),NewInteger(0),env);
UNPROTECT(1);

Duncan Murdoch



[Rd] creating environments in package's C code
Duncan Murdoch