[Rd] creating environments in package's C code

Jeff Horner jeff.horner at vanderbilt.edu
Thu Oct 1 21:19:33 CEST 2009


Simon Urbanek wrote:
> Jeff,
> 
> On Oct 1, 2009, at 12:37 , 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;
>>> }
>>
> 
> eek ... that some dangerous bit of code ;). I think Rf_NewEnviroment is 
> safer even if it's not the headers :P.

Interesting. I know that I patterned that function after some grepping 
for ENVSXP, probably src/main/serialize.c's ReadItem() as it's similar. 
Plus I only used what was available from the public headers.

So, if Rf_NewEnviroment is the right way to do it then make it public ;P.

> 
> 
>> 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;
>> }
> 
> I suspect you like reinventing the wheel ;). Your NewInteger is part of 
> the R API and is called ScalarInteger(). When you need something, 
> chances are that R has it already, so it's worth greping through the 
> headers (and sometimes even through the main sources).

Yes, that I created NewInteger is a grave oversight on my part. It's 
been around since R's first release (if my svn log research was 
correct). Thanks. I'm putting it on rapache's TODO list to take it out.

Jeff

> 
> Cheers,
> Simon
> 
> 
> 
>>
>>> 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);
>>> Best
>>> Jeff
>>> ______________________________________________
>>> 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
>>
>>
>



More information about the R-devel mailing list