[Rcpp-devel] Returning a named (and classed?) list from an RcppExport SEXP function

Dirk Eddelbuettel edd at debian.org
Fri Mar 12 19:11:29 CET 2010


On 12 March 2010 at 11:23, Douglas Bates wrote:
| Nice approach.  I presume that the Pairlist object is converted to an
| VECSXP in the process of being packaged for return.  I will play
| around a bit with expressions like
| 
| Rcpp::List res(Rcpp::PairList(Rcpp::Named(...), ...))

Not sure if that works with Rcpp::List as a returned object.
 
| I would like to have the capability of attaching an attribute named
| "class" to the VECSXP before returning it.

We do see attr() on RObject types as a quick grep on unitTests/* revelas
 
| > | An unrelated question -- has anyone looked at accessing S4 classed
| > | objects in Rcpp?  I have had considerable experience with S4 classes
| > | and objects and could keep such a project in mind as I begin to
| > | explore Rcpp.
| >
| > I'd be happy to go there (time permitting) but very gently as I am still much
| > more firmly in S3 land.  Romain may be more eager :)
| 
| One of the nice properties of S4 classed objects is that you can
| define validity checks for classes and bypass some of the code that
| does validity checking of arguments.

I include the S4 unit test file below. That's the closest we've come to docs :) 
 
| Perhaps you are assuming that c(1,4,9) generates an integer vector in
| this example.  In fact, c(1,4,9) is a numeric (in the sense of double
| precision) vector.  You need to write c(1L, 4L, 9L) to ensure you have
| an integer vector or coerce it with as.integer().

Yes, I am still trying to get used to that. So in that sense my test will
have been less rigid.  In this particular example it does work for both class
and new without fail when I submit c(1L, 4L, 9L)
 
| Yes, I like that idea of being able to use foo.begin() to access the
| pointer.  Part of my question related to whether I could count on
| getting the pointer to the original contents from R.  In some way I
| would need to check whether the R object had been coerced, and hence
| allocated new storage for its contents, or not.  That's not an
| immediate problem, though.

A fairly firm 'yes'. The classic API did more copying, the new API does a lot
more SEXP preservation.  You should be good.

Dirk

inst/unitTests/runit.S4.R below:


#!/usr/bin/r -t
#
# Copyright (C) 2010	Dirk Eddelbuettel and Romain Francois
#
# This file is part of Rcpp.
#
# Rcpp is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Rcpp is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.

.setUp <- function(){
	suppressMessages( require( inline ) )
}

test.S4 <- function(){
	funx <- cfunction(signature(x = "ANY" ), '
	RObject y(x) ;
	List res(5) ;
	res[0] = y.isS4() ;
	res[1] = y.hasSlot("x") ;
	res[2] = y.hasSlot("z") ;
	res[3] = y.slot("x") ;
	res[4] = y.slot("y") ;
	return res ;
	', Rcpp=TRUE, verbose=FALSE, includes = "using namespace Rcpp;" )
	setClass("track",
           representation(x="numeric", y="numeric"))
	tr <- new( "track", x = 2, y = 2 )
	checkEquals( funx(tr),
		list( TRUE, TRUE, FALSE, 2.0, 2.0 )
	, msg = "slot management" )
	
	funx <- cfunction(signature(x = "ANY" ), '
	RObject y(x) ;
	y.slot( "x" ) = 10.0 ;
	y.slot( "y" ) = 20.0 ;
	return R_NilValue ;
	', Rcpp=TRUE, verbose=FALSE, includes = "using namespace Rcpp;" )
	funx( tr )
	checkEquals( tr at x, 10.0 , msg = "slot('x') = 10" )
	checkEquals( tr at y, 20.0 , msg = "slot('y') = 20" )
	
	funx <- cfunction(signature(x = "ANY" ), '
	RObject y(x) ;
	y.slot( "foo" ) = 10.0 ;
	return R_NilValue ;
	', Rcpp=TRUE, verbose=FALSE, includes = "using namespace Rcpp;" )
	checkException( funx( tr ), msg = "slot does not exist" )
	
	funx <- cfunction(signature(x = "ANY" ), '
	RObject y(x) ;
	y.slot( "foo" ) ;
	return R_NilValue ;
	', Rcpp=TRUE, verbose=FALSE, includes = "using namespace Rcpp;" )
	checkException( funx( tr ), msg = "slot does not exist" )
	
	
}



-- 
  Registration is open for the 2nd International conference R / Finance 2010
  See http://www.RinFinance.com for details, and see you in Chicago in April!


More information about the Rcpp-devel mailing list