Hi, hopefully someone out there is good with foreach and iterators! I've been struggling with this:
I have created a custom iterator, inheriting from there iter class in the iterators package. The iterator and its methods are not exported from the package. Here is the iterator and a test function in a script that is reproducible and runnable, the iterator is called pairsRef:
library(Biostrings)
library(iterators)
library(foreach)    
setGeneric("maskSequences", function(object, seqnames, invert = TRUE, append = "union"){
  standardGeneric("maskSequences")
})
setMethod("maskSequences",
          signature("DNAMultipleAlignment", "character", "logical", "character"),
          function(object, seqnames, invert, append) {
            sequenceNames <- rownames(object)
            rowmask(object, append = append, invert = invert) <-
              which(sequenceNames %in% seqnames)
            return(object)
          })
pairsRef <- function(obj, ...){
  UseMethod('pairsRef')
}
pairsRef.DNAMultipleAlignment <-
  function(obj, ref = NULL, checkFun = function(x, ...) TRUE){
    state <- new.env()
    state$i <- 0L
    state$obj <- obj
    if(is.null(ref)){
      state$ref <- rownames(obj)[1]
    } else {
      state$ref <- ref
    }
    state$nonRefs <- rownames(obj)
    state$nonRefs <- state$nonRefs[state$nonRefs != state$ref]
    it <- list(state=state, checkFun = checkFun)
    class(it) <- c("pairsRef", "abstractiter", "iter")
    return(it)
  }
nextElem.pairsRef <- function(obj, ...){
  repeat {
    obj$state$i <- obj$state$i + 1L
    if(obj$state$i > length(obj$state$nonRefs))
      stop('StopIteration', call.=FALSE)
    pair <- maskSequences(obj$state$obj,
                          c(obj$state$ref, obj$state$nonRefs[obj$state$i]),
                          invert = TRUE,
                          append = "replace"
    )
    if(obj$checkFun(pair)){
      return(pair)
    }
  }
}
Test2 <- function(dna, ref){
  pit <- pairsRef(dna, ref = ref, checkFun = function(x) TRUE)
  results <- foreach(x = pit, .combine = c, .multicombine = TRUE) %do% {x}
  return(results)
}
dna <-
  readDNAMultipleAlignment(filepath =
                             system.file("extdata",
                                         "msx2_mRNA.aln",
                                         package="Biostrings"),
                           format="clustal")
Test2(dna, rownames(dna)[1])
However, I want to use this iterator to do foreach loops in a package of mine. If I put Test2 in a package (exported), and I have all the other functions in the package (unexported), and I have the package namespace import Biostrings, iterators, and foreach. It does not work. With a fresh R session, loading the package, and the running:
dna <-
  Biostrings::readDNAMultipleAlignment(filepath =
                             system.file("extdata",
                                         "msx2_mRNA.aln",
                                         package="Biostrings"),
                           format="clustal")
Test2(dna, rownames(dna)[1])
Is this because the custom iterator is internal to the package? Any help or suggestions are greatly appreciated.
If I export the iterator and it's functions from the package. Then all works fine. But I don't necessarily want to export iterators of the package.
I have tried to look at the code for `%do%` in foreach, and have found `doSEQ` has.... environmenty stuff ... it gets called with parent.frame() and such on.
Has anyone else used custom iterators and foreach in their packages? How did you do it?
Many thanks,
Ben.

A test for your solution would be to ensure that the package works when it is loaded but not attached, for instance if the iterator were use in a function
foo()then invoke foo without it being on the search path, in a new R sessionyourpkg::foo()without first sayinglibrary(foo). This is how a package that Imports: your package would see foo().