Checking multiple inheritance of S4 objects using R's C API

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Checking multiple inheritance of S4 objects using R's C API

egonulates
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]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Checking multiple inheritance of S4 objects using R's C API

Simon Urbanek
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 <[hidden email]> 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]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel