Skip to content
Prev 745 / 10988 Next

[Rcpp-devel] Rcpp modules : help with the design

Le 29/05/10 09:10, Romain Francois a ?crit :
>
Hi,

Few cup of coffee later, I have implemented option 1) :


######################################################################
require( Rcpp )
require( inline )

code <- ''

inc  <- '
class World {
public:
     World() : msg("hello"){}
     void set(std::string msg) { this->msg = msg; }
     std::string greet() { return msg; }

private:
     std::string msg;
};

void clearWorld( World* w){
	w->set( "" ) ;
}

RCPP_MODULE(yada){
	using namespace Rcpp ;
	
	class_<World>( "World" )
		.method( "greet", &World::greet )
		.method( "set", &World::set )
		.method( "clear", &clearWorld )
	;

}

'
fx <- cxxfunction( signature(), "", include = inc, plugin = "Rcpp" )

yada <- Rcpp:::Module( "yada", getDynLib( fx ) )


# grab the World class
World <- yada$World

# create a new World object
w <- new( World )

setMethod( "show", "World", function(object){
	msg <- object$greet()
	writeLines( paste( "message from World:", msg )  )
} )

######################################################################



 > w
message from World: hello




When the module is loaded (with the Module function), it registers the 
classes as simple extensions of the S4 class "C++Object" :

 > str( getClass( "C++Object" ) )
Formal class 'classRepresentation' [package "methods"] with 11 slots
   ..@ slots     :List of 3
   .. ..$ module  : atomic [1:1] externalptr
   .. .. ..- attr(*, "package")= chr "methods"
   .. ..$ cppclass: atomic [1:1] externalptr
   .. .. ..- attr(*, "package")= chr "methods"
   .. ..$ pointer : atomic [1:1] externalptr
   .. .. ..- attr(*, "package")= chr "methods"
   ..@ contains  : list()
   ..@ virtual   : logi FALSE
   ..@ prototype :Formal class 'S4' [package ""] with 0 slots
  list()
   ..@ validity  : NULL
   ..@ access    : list()
   ..@ className : atomic [1:1] C++Object
   .. ..- attr(*, "package")= chr "Rcpp"
   ..@ package   : chr "Rcpp"
   ..@ subclasses:List of 1
   .. ..$ World:Formal class 'SClassExtension' [package "methods"] with 
10 slots
   .. .. .. ..@ subClass  : chr "World"
   .. .. .. ..@ superClass: chr "C++Object"
   .. .. .. ..@ package   : chr ".GlobalEnv"
   .. .. .. ..@ coerce    :function (from, strict = TRUE)
   .. .. .. ..@ test      :function (object)
   .. .. .. ..@ replace   :function (from, to, value)
   .. .. .. ..@ simple    : logi TRUE
   .. .. .. ..@ by        : chr(0)
   .. .. .. ..@ dataPart  : logi FALSE
   .. .. .. ..@ distance  : num 1
   ..@ versionKey:<externalptr>
   ..@ sealed    : logi FALSE


This way we can have both:
- internal dispatch of the traditional OO form : object$method( ... )
- S4 dispatch : generic( object, ... )


My next move is probably going to be melting both, so that we can define 
classic methods such as show internally, something like:

class_<World>( "World" )
		.method( "greet", &World::greet )
		.method( "set", &World::set )
		.method( "clear", &clearWorld )

		.S4_method( "show", &showWorld )
	;

Romain