Hello,

One of the development routes of Rcpp is the concept of modules. In short an Rcpp module is a collection of C++ functions and classes directly exposed to R. The longer version of the description can be found in the vignette [1].

When we expose a C++ class through a module, i.e:

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

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

        }
        

> yada <- Module( "yada" )

an S4 class is also created so that we can achieve R-level method dispatch:

> setMethod( "show", "World", function(object){
        writeLines( sprintf( "<World object> : %s " , object$greet() ) )
} )

> w <- new( yada$World )
> w
<World object> : hello


Now, the name used for the S4 dispatch is simply "World", which might (as John Chambers said here earlier) cause problems. For example what happens if two modules decide to expose the same class, etc ...

So I'd like to do some sort of name mangling of the class to lower the chances of clashes, so instead of just "World" the class name could use something that identifies the module (for example a character version of the pointer address.

> sprintf( "rcpp_module_%s_%s", Rcpp:::externalptr_address( yada ), "World" )
[1] "rcpp_module_0x102f499b8_World"

We could hide this in a function so that we can do :

> setMethod( "show", somefunction( yada, "World" ), ... )

but I find this a little bit too verbose, and would prefer something like this:

> setMethod( "show", yada::World , ... )

Unfortunately, it seems that if I define a method for :: it breaks the original use, because of non standard evaluation:

> setMethod( "::", "Module", function(pkg, name ){
+
+ sprintf( "rcpp_module_%s_%s", Rcpp:::externalptr_address( pkg ), "World" )
+ }
+ )
Une nouvelle fonction générique est créée pour "::" dans ".GlobalEnv"
[1] "::"

> mod::World
[1] "rcpp_module_0x102f499b8_World"
>
> stats::rnorm
Erreur : objet 'stats' introuvable
Erreur dans stats::rnorm :
erreur lors de l'évaluation de l'argument 'pkg' lors de la sélection d'une méthode pour la fonction '::'


Any idea to work around that ?



Another way would be to use $ instead, so we would :

> setMethod( "show", yada$World , ... )

but again this does not work because the signature in setMethod expects a character vector and yada$World is not (this is a C++Class object).


> signature( x = mod$World )
Erreur dans signature(x = mod$World) :
mauvaise classe spécifiée pour l'élément 1 (doit être une simple chaîne de caractères)

Maybe one way to deal with that is to make C++Class extend the character class ...


Ideas ?


[1] : http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-modules.pdf

--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/aJHNLV : Rmetrics slides
|- http://bit.ly/98Uf7u : Rcpp 0.8.1
`- http://bit.ly/c6YnCi : graph gallery collage

_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to