Rcpp

2014-07-03 20 views
14

'da bir R uyarısı nasıl üretilir? Yığında C++ destructor'lar üzerinde bir longjmp içerdiğinden Rcpp'de Rf_error() numaralı çağrıdan kaçınılması gerektiğini biliyoruz. Bu yüzden, C++ istisnalarını Rcpp koduna atmayı tercih ediyoruz (throw Rcpp::exception("...") veya stop("...") işlevi aracılığıyla). Ancak, R uyarıları Rf_error() numaralı çağrıya neden olabilir (bu davranış warn seçeneğine bağlıdır). Yani, Rf_warning() numaralı telefona yapılan bir çağrı da riskli.Rcpp

Rcpp::sourceCpp(code = ' 

    #include <Rcpp.h> 
    using namespace Rcpp; 

    class Test { 
     public: 
     Test() { Rcout << "start\\n"; } 
     ~Test() { Rcout << "end\\n"; } 
    }; 

    // [[Rcpp::export]] 
    void test() { 
     Test t; 
     Rf_warning("test"); 
    } 
') 

options(warn=10) 
test() 
## start 
## Error in test() : (converted from warning) test 

Yıkıcıya çağrılmadığını görüyoruz ("son" mesajı yok).

C++ - yıkıcı dostu bir şekilde bir R uyarısı nasıl oluşturulur? Doğru davranış warn>2 eğer verir

// [[Rcpp::export]] 
void test() { 
    Test t; 
    Function warning("warning"); 
    warning("test"); // here R errors are caught and transformed to C++ exceptions 
} 

:

start 
end 
Error in eval(expr, envir, enclos) : (converted from warning) test 

kimsenin daha iyi olup olmadığını merak Rcpp gelen R'ın warning işlevini çağırarak kapsar ile çözümlerin

cevap

10

Bir Ben geldi bunun için bir fikir.

+5

Bunun iyi olması gerektiğini düşünüyorum - sadece statik nesnelere dikkat edin. –

6

yerine (try/catch etrafında sarıcı olan) stop() kullanarak öneriyoruz: biraz değiştirilmiş sizin kod ile

:

R> sourceCpp("/tmp/throw.cpp") 

R> options(warn=10) 

R> #test() 
R> test2() 
start 
end 
Error in eval(expr, envir, enclos) (from srcConn#3) : test2 
R> 

:

#include <Rcpp.h> 
using namespace Rcpp; 

class Test { 
public: 
    Test() { Rcout << "start\n"; } 
    ~Test() { Rcout << "end\n"; } 
}; 

// [[Rcpp::export]] 
void test() { 
    Test t; 
    Rf_warning("test"); 
} 

// [[Rcpp::export]] 
void test2() { 
    Test t; 
    stop("test2"); 
} 

/*** R 
options(warn=10) 
#test() 
test2() 
*/ 

ben istenilen davranışı olsun longjmp sorunu bilinmektedir, ancak nesneleri gevşetmek zorunda olduğumuz mekanizmalardan kaçınarak kazanamazsınız.

+0

Tamam, @DirkEddelbuettel, 'longjmp' sorununun tamamen farkındayım, ancak genellikle bir uyarı değil, bir hata oluşturmak istiyorum. Ama eğer 2'yi uyarırsam, temiz bir şekilde başarısız olmasını istiyorum. – gagolews

+2

Oh, pardon, sonra sorumu yanlış anladım. Hâlâ hala kullanımda erken saatlerdeR :) Belki de R'nin 'uyarı() 'sine bir C++ erişim noktasına ihtiyacımız var ... –

+0

Böyle bir erişim noktası hile yapabilirdi :) – gagolews

İlgili konular