The documentation lies :) What you did is equivalent to the R function:
classR = function(x) attributes(x)$class
What R does when you call class
is this:
SEXP R_data_class(SEXP obj, Rboolean singleString)
{
SEXP value, klass = getAttrib(obj, R_ClassSymbol);
int n = length(klass);
if(n == 1 || (n > 0 && !singleString))
return(klass);
if(n == 0) {
SEXP dim = getAttrib(obj, R_DimSymbol);
int nd = length(dim);
if(nd > 0) {
if(nd == 2)
klass = mkChar("matrix");
else
klass = mkChar("array");
}
else {
SEXPTYPE t = TYPEOF(obj);
switch(t) {
case CLOSXP: case SPECIALSXP: case BUILTINSXP:
klass = mkChar("function");
break;
case REALSXP:
klass = mkChar("numeric");
break;
case SYMSXP:
klass = mkChar("name");
break;
case LANGSXP:
klass = lang2str(obj, t);
break;
default:
klass = type2str(t);
}
}
}
else
klass = asChar(klass);
PROTECT(klass);
value = ScalarString(klass);
UNPROTECT(1);
return value;
}
So you can see that it does a bunch of checks for all those cases where you got NULL
.
An easy option for you is to just call class
from your function:
eval(lang2(install("class"), x), R_GlobalEnv)