creating environments in package's C code

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

creating environments in package's C code

Martin Becker
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,

  Martin

--
Dr. Martin Becker
Statistics and Econometrics
Saarland University
Campus C3 1, Room 206
66123 Saarbruecken
Germany

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Jeffrey Horner
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;
}


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

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Simon Urbanek
In reply to this post by Martin Becker

On Oct 1, 2009, at 11:33 , 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.
>

Rf_NewEnvironment is the function that does it, e.g.,
Rf_NewEnvironment(R_NilValue, R_NilValue, parent)
it's not part of the official API (headers) but it is visible.
For hashed environments it's R_NewHashedEnv().

Cheers,
Simon

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Jeffrey Horner
In reply to this post by Jeffrey Horner
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);
>
> Best
>
> Jeff
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Simon Urbanek
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.


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

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
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Duncan Murdoch
In reply to this post by Jeffrey Horner
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

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: creating environments in package's C code

Jeffrey Horner
In reply to this post by Simon Urbanek
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
>>> ______________________________________________
>>> [hidden email] mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Because it's Friday. was creating environments in package's C code

Jeffrey Horner
In reply to this post by Simon Urbanek
Simon Urbanek wrote on 10/01/2009 11:51 AM:
[...]
> 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).

I am reminded of what Robert Gentleman said at DSC 2005 during the R/S
round-chair discussion: "Brian Ripley is the only one I know who keeps R
in his frontal lobe."

I can only aspire to such greatness, Simon.

Jeff

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Because it's Friday. was creating environments in package's C code

Spencer Graves-3
      I hope you will forgive a serious comment on this thread, but the
new "sos" package makes "greping through the headers" shockingly easy.  
It returns the 'RSiteSearch( ___ , "function")' information in a
data.frame of class "findFn" sorted to put the package with the most
matches first.  Duncan Murdoch wrote a "???" alias for this "findFn"
function.  Union and intersection operators are defined for
"findFn"objects.  The "findFn2xls" function writes an Excel file with
three sheets giving an extended package summary, the matches (including
the URLs), and the call.  An article on this is scheduled to appear in
the next issue of "R Journal" and is available now via vignette('sos').


      This "sos" package is not as good as greping Ripley's frontal
lobe, but it makes it quite easy to do a literature search of all
contributed R packages.


      Spencer


Jeffrey Horner wrote:

> Simon Urbanek wrote on 10/01/2009 11:51 AM:
> [...]
>> 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).
>
> I am reminded of what Robert Gentleman said at DSC 2005 during the R/S
> round-chair discussion: "Brian Ripley is the only one I know who keeps
> R in his frontal lobe."
>
> I can only aspire to such greatness, Simon.
>
> Jeff
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>


--
Spencer Graves, PE, PhD
President and Chief Operating Officer
Structure Inspection and Monitoring, Inc.
751 Emerson Ct.
San José, CA 95126
ph:  408-655-4567

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel