Hello,
Consider this :
setClass("track", representation(x="numeric", y="numeric"))
[1] "track"
o <- new( "track", x = 1, y = 2 )
for( i in o ){
+ cat( "hello\n")
+ }
Error: invalid type/length (S4/1) in vector allocation
This happens at those lines of do_for:
n = LENGTH(val);
PROTECT_WITH_INDEX(v = allocVector(TYPEOF(val), 1), &vpi);
because allocVector( S4SXP, 1) does not make sense.
What about detecting S4SXP and attempt to call as.list, similarly to
what lapply does ?
as.list.track <- function(x, ...){ list( x = x...@x, y = x...@y ) }
lapply( o, identity )
$x
[1] 1
$y
[1] 2
That would make for loops more generic, and make it possible to
implement custom "iterators". I'm attaching a patch to eval.c that does
just that. For example :
> setClass("iterator", representation(to="integer"))
[1] "iterator"
> o <- new( "iterator", to = 4L )
> setGeneric( "as.list" )
[1] "as.list"
> setMethod( "as.list", "iterator", function(x, ...) {
+ seq_len( x...@to )
+ })
[1] "as.list"
>
> for( i in o ){
+ cat( i, "\n" )
+ }
1
2
3
4
Obviously that is the cheap way of doing it, something better would be
to abstract a bit more what is an "iterator".
For example in java iterators implement just two methods : hasNext()
that indicates if there is a next object and next() that returns the
next object.
For the long story, one motivation for this is actually to deal with
java iterators (with the devel version of rJava, and this patch), you
might do something like this:
> v <- new( J("java/util/Vector") )
> v$add( new( J("java/awt/Point"), 10L, 10L ) )
[1] TRUE
> v$add( new( J("java/lang/Double"), 10 ) )
[1] TRUE
> for( item in v ){
+ print( item$getClass()$getName() )
+ }
[1] "java.awt.Point"
[1] "java.lang.Double"
Where the as.list method for java object references returns a list that
is filled by iterating over the object if it implements the Iterable
interface.
The drawback here is that one has to first fully retrieve the list, by
iterating in java, and then process it in R, by iterating again in R.
Romain
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/BcPw : celebrating R commit #50000
|- http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
`- http://tr.im/yw8E : New R package : sos
Index: src/main/eval.c
===================================================================
--- src/main/eval.c (revision 50047)
+++ src/main/eval.c (working copy)
@@ -1046,6 +1046,17 @@
PROTECT(val = eval(val, rho));
defineVar(sym, R_NilValue, rho);
+ /* deal with the S4 case, try to dispatch to as.list */
+ if( TYPEOF(val) == S4SXP ){
+ SEXP expr ;
+ /* probably should use DispatchOrEval here */
+ PROTECT( expr = lang2(install("as.list"), val ));
+ PROTECT( ans = eval( expr, rho ) ) ;
+ val = ans ;
+ UNPROTECT(3); /* expr, ans and val from above*/
+ PROTECT(val);
+ }
+
/* deal with the case where we are iterating over a factor
we need to coerce to character - then iterate */
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel