Emre Gonulates
2021-Feb-15 23:03 UTC
[Rd] Checking multiple inheritance of S4 objects using R's C API
Hi, Suppose I have the following two classes in R: setClass("Person", representation(name = "character", age = "numeric")) setClass("Employee", representation(boss = "Person"), contains = "Person") I can successfully check inheritance in base R: employee <- new("Employee", name = "Jack", age = 25) inherits(employee, "Employee") #> [1] TRUE inherits(employee, "Person") #> [1] TRUE I could not achieve the same in Rcpp: Rcpp::cppFunction(' void check_class(Rcpp::S4 x) { Rcout << "Class: " << as<std::string>(x.attr("class")) << std::endl; Rcout << "Rf_inherits(x, \\"Employee\\") : " << Rf_inherits(x, "Employee") << std::endl; Rcout << "Rf_inherits(x, \\"Person\\") : " << Rf_inherits(x, "Person") << std::endl; Rcout << "R_extends : " << R_extends(x, Rf_mkString("Person"), R_GlobalEnv) << std::endl; }') check_class(employee) #> Class: Employee #> Rf_inherits(x, "Employee") : 1 #> Rf_inherits(x, "Person") : 0 #> R_extends : #> Error in extends(new("Employee", boss = new("Person", name character(0), : 'class1' must be the name of a class or a class definition I expected `Rf_inherits(x, "Person")` to be true as well. How can I check whether an object inherits from parent classes in R's C API? Thanks, Emre. P.S. This question originally posted <a href=" https://stackoverflow.com/q/66201929/2275286">here</a>. [[alternative HTML version deleted]]
Simon Urbanek
2021-Feb-16 01:58 UTC
[Rd] Checking multiple inheritance of S4 objects using R's C API
Emre, inherits() was designed for S3 classes and at C level only ever works for S3 classes. In S4 world you should use is(). There is no equivalent C-level API for is() so, unfortunately, you likely have to use Rf_eval() of is(x, "class"). At low-level there is R_S4_extends() which allows you to get the list of superclasses for S4 objects, but according to the definition of some people it is not part of the official R API so your mileage may vary. Cheers, Simon> On Feb 16, 2021, at 12:03 PM, Emre Gonulates <egonulates at gmail.com> wrote: > > Hi, > > Suppose I have the following two classes in R: > > > setClass("Person", representation(name = "character", age = "numeric")) > setClass("Employee", representation(boss = "Person"), contains = "Person") > > > I can successfully check inheritance in base R: > > > employee <- new("Employee", name = "Jack", age = 25) > > inherits(employee, "Employee") > #> [1] TRUE > inherits(employee, "Person") > #> [1] TRUE > > > I could not achieve the same in Rcpp: > > > Rcpp::cppFunction(' > void check_class(Rcpp::S4 x) { > Rcout << "Class: " << as<std::string>(x.attr("class")) << std::endl; > Rcout << "Rf_inherits(x, \\"Employee\\") : " << Rf_inherits(x, > "Employee") << std::endl; > Rcout << "Rf_inherits(x, \\"Person\\") : " << Rf_inherits(x, "Person") > << std::endl; > Rcout << "R_extends : " << R_extends(x, Rf_mkString("Person"), > R_GlobalEnv) << std::endl; > }') > > check_class(employee) > #> Class: Employee > #> Rf_inherits(x, "Employee") : 1 > #> Rf_inherits(x, "Person") : 0 > #> R_extends : > #> Error in extends(new("Employee", boss = new("Person", name > character(0), : 'class1' must be the name of a class or a class definition > > > I expected `Rf_inherits(x, "Person")` to be true as well. > > How can I check whether an object inherits from parent classes in R's C API? > > Thanks, > Emre. > > > P.S. This question originally posted <a href=" > https://stackoverflow.com/q/66201929/2275286">here</a>. > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >