Skip to content

[Rcpp-devel] Designing Rcpp modules - allow access to fields or to field accessor methods?

6 messages · Douglas Bates, Andrew Redd, Romain Francois +1 more

#
My C++ coding style (such as it is) has been influenced by reading
Frank Bokken's "C++ Annotations".  I keep most data members of classes
private or protected and usually with names like d_x, d_y, d_weights,
etc. then provide accessor functions named x, y, weights, etc.
Generally the accessors return const references.

If I export such a class in an Rcpp module I can't allow field access
but can allow access from R to the accessor methods.  This seems
slightly awkward in that the user must know to use

myRefObj$x()

instead of

myRefObj$x

to access the x field.  Any strong opinions about fields access versus
access to field accessor methods?

As an example, one of my classes ends up looking like this
Generator object for class "Rcpp_lmResp":

No fields defined

 Class Methods:
    "callSuper", "export", "finalize", "import", "initFields",
"initialize", "mu",
"offset", "sqrtrwt", "sqrtXwt", "updateMu", "updateWts", "wrss", "wtres", "y"


 Reference Superclasses:
    "envRefClass"

but all those methods except updateMu and updateWts are field accessors.

One advantage of this method is that one can't make changes to those
fields at the R level, which I like because I am paranoid about
introducing inconsistencies in the fields.
#
Isn't this sort of thing what the .property is for in modules?  Or are
you looking for something else
-Andrew
On Thu, Nov 18, 2010 at 2:31 PM, Douglas Bates <bates at stat.wisc.edu> wrote:
#
Le 18/11/10 22:31, Douglas Bates a ?crit :
You can use .property instead of .field to short circuit x back to d_x.

Consider this class (which I believe follows the convention you mention):

class Simple {
public:

     Simple( double x ) : d_x(x){} ;

     const double& x(){ return d_x ;}

private:
     double d_x ;
		
} ;

In R, you'd want to be able to do :

r <- new( Simple, 10 )
r$x

but not :

r$x <- 20



Then .property is what you need:

RCPP_MODULE(mod){

	class_<Simple>( "Simple" )

	    .constructor(init_1<double>())
	    .property( "x" , &Simple::x )
	
	;
}


When the third argument is not given, the property is considered read only.

Romain
#
Le 18/11/10 22:41, Romain Francois a ?crit :
For convenience, here is the full example :

require( Rcpp )
require( inline )
inc <- '

class Simple {
public:

     Simple( double x ) : d_x(x){} ;

     const double& x(){ return d_x ;}

private:
     double d_x ;
		
} ;

RCPP_MODULE(mod){

	class_<Simple>( "Simple" )

	    .constructor(init_1<double>())
	
		.property( "x" , &Simple::x )
		;
		

}
'

fx <- cxxfunction( , '', includes = inc, plugin = "Rcpp" )
mod <- Module( "mod", getDynLib( fx ) )
Simple <- mod$Simple
r <- new( Simple, 10 )
r$x
r$x <- 20
#
Thanks again Romain.  Now that you mention it I remember.

On Thu, Nov 18, 2010 at 3:41 PM, Romain Francois
<romain at r-enthusiasts.com> wrote:
1 day later
#
Romain's solution is almost certainly the way to go.

Just for completeness, note that you can define a field on the R side to 
be an accessor function as well, using the standard mechanism for active 
bindings; i.e., an R function (anonymous if you want) that returns the 
field if called without argument and sets it (or gives an error) with 
an  argument.

John
On 11/18/10 1:47 PM, Douglas Bates wrote: