Rcpp生成的S4类的S4方法似乎仍然需要.onLoad()

时间:2018-11-18 18:00:27

标签: r class methods rcpp s4

我找不到不使用show来将S4 .onLoad方法添加到导出的S4类的方法。 Rcpp gallery example建议使用“ Rcpp_yourclassname”作为对象名,但实际上我的程序包抱怨找不到该类:

Loading RcppS4show
in method for ‘show’ with signature ‘"Rcpp_Num"’: no definition for class “Rcpp_Num”

通过使用Rcpp模块软件包框架,可以轻松地重现此内容:

# R console:
Rcpp::Rcpp.package.skeleton("RcppS4show", path = "/tmp", module = TRUE)
# In /tmp/RcppS4show edit the file:
#   R/zzz.R
# ... as described below.
setwd("/tmp/RcppS4show")
devtools::load_all()

将此添加到R/zzz.R的底部:

setMethod("show", "Rcpp_Num", function(object) {
    writeLines(paste("Num(x, y) =", object$x, object$y))
})

我可以通过将loadModulesetMethod函数包装在.onLoad中来解决此问题:

.onLoad <- function(libname, pkgname) {
    loadModule("NumEx", TRUE)

    setMethod("show", "Rcpp_Num", function(object) {
        writeLines(paste("Num(x, y) =", object$x, object$y))
    })
}

现在我可以看到我的show方法起作用了:

# R console:
new(Num)
#> Num(x, y) = 0 0

然而,模块框架文档和Rcpp-modules vignette都说明不建议使用.onLoad来支持loadModule()

此外,不得不滥用.onLoad()会使devtools::check()注意到我的writeLines()方法中的show是不正确的做法:

> checking R code for possible problems ... NOTE
  File ‘RcppS4show/R/zzz.R’:
    .onLoad calls:
      writeLines(paste("Num(x, y) =", object$x, object$y))

  Package startup functions should use ‘packageStartupMessage’ to
    generate messages.
  See section ‘Good practice’ in '?.onAttach'.

是否可以使用不使用.onLoad来注册S4方法?

1 个答案:

答案 0 :(得分:3)

也许我想念一些东西,但是...

为什么不只在C ++端定义show方法? (也许这就是Dirk说“我只需一次定义所有模块”时的意思。)

运行后

Rcpp::Rcpp.package.skeleton("RcppS4show", path = "/tmp", module = TRUE)

要创建包,我将Num.cpp编辑为以下内容

#include <Rcpp.h>

class Num {                     // simple class with two private variables
public:                         // which have a getter/setter and getter
    Num() : x(0.0), y(0){} ;

    double getX() { return x ; }
    void setX(double value){ x = value ; }

    int getY() { return y ; }

    // Show method
    void show() { Rcpp::Rcout << "Num(x, y) = " << x << " " << y << "\n"; }

private:
    double x ;
    int y ;
};

RCPP_MODULE(NumEx){
    using namespace Rcpp ;

    class_<Num>( "Num" )

    .default_constructor()

    // read and write property
    .property( "x", &Num::getX, &Num::setX )

    // read-only property
    .property( "y", &Num::getY )

    // show method
    .method("show", &Num::show)

    ;

}

然后从R

setwd("/tmp/RcppS4show")
devtools::load_all()
new(Num)
# Num(x, y) = 0 0
devtools::check()
# Most of the output is omitted, but...
# Status: OK
# 
# R CMD check results
# 0 errors | 0 warnings | 0 notes
showMethods("show")
# Function: show (package methods)
# Some output omitted...
# object="Rcpp_Num"
# More output omitted...