Метод S4 для сгенерированного Rcpp класса S4 все еще нуждается в .onLoad () - PullRequest
0 голосов
/ 18 ноября 2018

Я не могу найти способ добавить метод S4 show в экспортируемый класс S4 без использования .onLoad. Пример галереи Rcpp предлагает "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))
})

Я могу обойти это, обернув функции loadModule и setMethod в.onLoad:

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

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

Теперь я вижу, как работает мой метод показа:

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

Однако, как документация по каркасу модуля, так и виньетка Rcpp-modules объяснятьчто .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'.

Есть ли способ зарегистрировать методы S4 без использования .onLoad?

1 Ответ

0 голосов
/ 19 ноября 2018

Возможно, я что-то упускаю, но ...

Почему бы просто не определить метод show на стороне C ++?(Возможно, именно это имел в виду Дирк, когда сказал: «Я просто определяю все свои модули сразу»).

После запуска

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