-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathutilities.r
77 lines (71 loc) · 2.58 KB
/
utilities.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#' Helper function that determines whether an object inherits from a
#' StopIteration exception
#'
#' Returns \code{TRUE} if the \code{object} resulted from a StopIteration
#' exception when \code{\link[iterators]{nextElem}} is called, and \code{FALSE}
#' otherwise.
#'
#' @param object an R object
#' @return \code{TRUE} if \code{object} resulted from a StopIteration
#' exception. Otherwise, \code{FALSE}.
stop_iteration <- function(object) {
inherits(object, "try-error") && object == "Error : StopIteration\n"
}
#' Helper function that determines the length of an iterator object
#'
#' Returns the length of an iterator object. In the case that the iterator's
#' length is \code{NULL}, a value of 1 is returned by default. This value can be
#' set using the \code{default} argument.
#'
#' @param object an iterator object
#' @param default the value returned when an iterator has \code{NULL} length
#' @return integer
iter_length <- function(object, default=1) {
ifelse(is.null(object$length), default, object$length)
}
#' Helper function that determines whether is an iterator object
#'
#' Returns \code{TRUE} if the \code{object} is an object of class \code{iter},
#' and \code{FALSE} otherwise.
#'
#' @param object an R object
#' @return logical value indicating whether \code{object} is of class
#' \code{iter}
is_iterator <- function(object) {
inherits(object, "iter")
}
#' Calls iterators::nextElem(). If error, returns default value.
#'
#' Returns the next element of \code{object}. In the case a StopIteration
#' exception is thrown, the \code{default} value is returned instead.
#'
#' @param object an iterable object
#' @param default default value returned if a StopIteration exception is thrown
#' @param silent Should any errors be suppressed without explicitly notifying
#' the user? Default. Yes
#' @return the next element of \code{object}
try_nextElem <- function(object, default=NA, silent=TRUE) {
next_elem <- try(iterators::nextElem(object), silent=silent)
if (stop_iteration(next_elem)) {
next_elem <- default
}
next_elem
}
#' Performs a deep copy of an iterator
#'
#' This function is useful when an iterator needs to be copied with a new
#' \code{state} environment.
#'
#' @export
#' @param iterator an iterator object that inherits from class 'iter'
#' @return a new iterator with its own state
iter_deepcopy <- function(iterator) {
iter_copy <- iterator
iter_copy$state <- new.env()
# Clones iterator's state into iter_copy's state
state_vars <- ls(envir=iterator$state)
for (var_i in state_vars) {
iter_copy$state[[var_i]] <- iterator$state[[var_i]]
}
iter_copy
}