Running 'aperm.R' [1s]
  Running 'as.listenv.R' [161s]
  Running 'as.vector.R' [0s]
  Running 'get_variable,dimensions.R' [0s]
  Running 'get_variable.R' [160s]
  Running 'lapply.R' [0s]
  Running 'listenv,dimensions.R' [0s]
  Running 'listenv.R' [173s]
  Running 'parse_env_subset,dimensions.R' [151s]
  Running 'parse_env_subset.R' [0s]
  Running 'undim.R' [0s]
  Running 'utils.R' [148s]
Running the tests in 'tests/as.listenv.R' failed.
Complete output:
  > library("listenv")
  > 
  > ovars <- ls(envir = globalenv())
  > oopts <- options(warn = 1)
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Single-element assignments and subsetting
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- list(a = 1, b = 2, c = 3)
  > str(x)
  List of 3
   $ a: num 1
   $ b: num 2
   $ c: num 3
  > y <- as.listenv(x)
  > print(y)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > stopifnot(identical(as.list(y), x))
  > z <- as.listenv(y)
  > stopifnot(identical(as.list(y), as.list(z)))
  > 
  > e <- new.env()
  > e$a <- 1
  > e$b <- 2
  > e$c <- 3
  > y <- as.listenv(e)
  > print(y)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > stopifnot(identical(as.list(y), as.list(e)))
  > 
  > x <- c(a = 1, b = 2, c = 3)
  > y <- as.listenv(x)
  > print(y)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > stopifnot(identical(as.list(y), as.list(x)))
  > 
  > ## Cleanup
  > options(oopts)
  > rm(list = setdiff(ls(envir = globalenv()), ovars), envir = globalenv())
  > 
  > proc.time()
     user  system elapsed 
     0.21    0.06    0.26 
Running the tests in 'tests/get_variable.R' failed.
Complete output:
  > library("listenv")
  > 
  > ovars <- ls(envir = globalenv())
  > oopts <- options(warn = 1)
  > 
  > x <- listenv()
  > length(x) <- 3L
  > names(x) <- c("a", "b", "c")
  > stopifnot(length(x) == 3L)
  > print(mapping(x))
   a  b  c 
  NA NA NA 
  > 
  > var <- get_variable(x, "a")
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 3L)
  > print(mapping(x))
   a  b  c 
  NA NA NA 
  > 
  > var <- get_variable(x, "b")
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 3L)
  > print(mapping(x))
   a  b  c 
  NA NA NA 
  > 
  > var <- get_variable(x, "c")
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 3L)
  > print(mapping(x))
   a  b  c 
  NA NA NA 
  > 
  > var <- get_variable(x, "d")
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 4L)
  > print(mapping(x))
    a   b   c   d 
   NA  NA  NA "d" 
  > 
  > var <- get_variable(x, 4L)
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 4L)
  > print(mapping(x))
    a   b   c   d 
   NA  NA  NA "d" 
  > 
  > x$b <- 2
  > var <- get_variable(x, "b")
  > stopifnot(!is.na(var))
  > stopifnot(length(x) == 4L)
  > print(mapping(x))
    a   b   c   d 
   NA "b"  NA "d" 
  > 
  > var <- get_variable(x, length(x) + 1L)
  > stopifnot(length(x) == 5L)
  > print(names(x))
  [1] "a" "b" "c" "d" "" 
  > print(mapping(x))
                        a                       b                       c 
                       NA                     "b"                      NA 
                        d                         
                      "d" ".listenv_var_1.000000" 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Allocation
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > length(x) <- 3L
  > print(x[[1]])
  NULL
  > print(x[[2]])
  NULL
  > print(x[[3]])
  NULL
  > 
  > ## Out-of-bound subsetting
  > res <- try(x[[0]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > ## Out-of-bound subsetting
  > res <- try(x[[4]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > print(get_variable(x, 1L, mustExist = FALSE))
  [1] ".listenv_var_1.000000"
  > print(get_variable(x, 2L, mustExist = FALSE))
  [1] ".listenv_var_2.000000"
  > print(get_variable(x, 3L, mustExist = FALSE))
  [1] ".listenv_var_3.000000"
  > 
  > ## Out-of-bound element
  > res <- try(var <- get_variable(x, 0L, mustExist = TRUE), silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > ## Out-of-bound element
  > res <- try(var <- get_variable(x, length(x) + 1L, mustExist = TRUE),
  +            silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Exception handling
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > length(x) <- 3L
  > names(x) <- c("a", "b", "c")
  > 
  > ## Non-existing element
  > res <- try(var <- get_variable(x, "z", mustExist = TRUE), silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(var <- get_variable(x, c("a", "b")), silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(var <- get_variable(x, 1 + 2i), silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > 
  > 
  > ## Cleanup
  > options(oopts)
  > rm(list = setdiff(ls(envir = globalenv()), ovars), envir = globalenv())
  > 
  > proc.time()
     user  system elapsed 
     0.23    0.01    0.23 
Running the tests in 'tests/listenv.R' failed.
Complete output:
  > library("listenv")
  > 
  > ovars <- ls(envir = globalenv())
  > oopts <- options(warn = 1)
  > with_r_330 <- function(expr) {
  +   if (getRversion() < "3.3.0") return()
  +   eval(substitute(expr), envir = parent.frame(), enclos = baseenv())
  + }
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Allocation
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > print(x)
  A 'listenv' vector with 0 elements (unnamed).
  > stopifnot(length(x) == 0)
  > stopifnot(is.null(names(x)))
  > with_r_330({
  +   stopifnot(identical(lengths(x), integer(0L)))
  + })
  > 
  > ## Named, empty list environment
  > x <- listenv()
  > names(x) <- character(0L)
  > print(x)
  A 'listenv' vector with 0 elements (named).
  > 
  > x <- listenv(a = 1)
  > print(x)
  A 'listenv' vector with 1 element ('a').
  > stopifnot(length(x) == 1)
  > stopifnot(identical(names(x), c("a")))
  > stopifnot(identical(x$a, 1))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(a = 1L)))
  + })
  > 
  > x <- listenv(a = 1, b = 2:3)
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(x$a, 1), identical(x$b, 2:3))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(a = 1L, b = 2L)))
  +   stopifnot(identical(lengths(x, use.names = FALSE), c(1L, 2L)))
  + })
  > 
  > x <- listenv(b = 2:3, .a = 1)
  > print(x)
  A 'listenv' vector with 2 elements ('b', '.a').
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("b", ".a")))
  > stopifnot(identical(x$.a, 1), identical(x$b, 2:3))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(b = 2L, .a = 1L)))
  + })
  > 
  > x <- listenv(length = 3, a = 1)
  > print(x)
  A 'listenv' vector with 2 elements ('length', 'a').
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("length", "a")))
  > stopifnot(identical(x$length, 3), identical(x$a, 1))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(length = 1L, a = 1L)))
  + })
  > 
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Single-element assignments and subsetting
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > print(x)
  A 'listenv' vector with 0 elements (unnamed).
  > print(length(x))
  [1] 0
  > print(names(x))
  NULL
  > stopifnot(length(x) == 0)
  > 
  > x$a <- 1
  > print(x)
  A 'listenv' vector with 1 element ('a').
  > print(length(x))
  [1] 1
  > print(names(x))
  [1] "a"
  > stopifnot(length(x) == 1)
  > stopifnot(identical(names(x), c("a")))
  > stopifnot(identical(x$a, 1), is.null(x$b))
  > 
  > x$b <- 2
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(x$b, 2))
  > 
  > x$a <- 0
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(x[["a"]], 0))
  > 
  > x$"a" <- 1
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(x$a, 1))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(a = 1L, b = 1L)))
  + })
  > 
  > x[["a"]] <- 0
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > 
  > 
  > key <- "b"
  > x[[key]] <- 3
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(x$b, 3), identical(x[["b"]], 3), identical(x[[key]], 3))
  > 
  > x[[3]] <- 3.14
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', '').
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] "a" "b" "" 
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "")))
  > stopifnot(identical(x[[3]], 3.14))
  > 
  > names(x) <- c("a", "b", "c")
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "c")))
  > stopifnot(identical(x[[3]], 3.14), identical(x[["c"]], 3.14),
  +           identical(x$c, 3.14))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(a = 1L, b = 1L, c = 1L)))
  + })
  > 
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Multi-element subsetting
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Assert than no false names are introduced
  > x <- listenv()
  > x[1:3] <- list(1, NULL, 3)
  > print(x)
  A 'listenv' vector with 3 elements (unnamed).
  > stopifnot(is.null(names(x)))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(1L, 0L, 1L)))
  + })
  > 
  > y <- x[]
  > print(y)
  A 'listenv' vector with 3 elements (unnamed).
  > stopifnot(length(y) == length(x))
  > stopifnot(all.equal(y, x))
  > stopifnot(!identical(y, x))
  > stopifnot(is.null(names(y)))
  > with_r_330({
  +   stopifnot(identical(lengths(y), c(1L, 0L, 1L)))
  + })
  > 
  > y <- x[1]
  > print(y)
  A 'listenv' vector with 1 element (unnamed).
  > stopifnot(is.null(names(y)))
  > 
  > y <- x[2:3]
  > print(y)
  A 'listenv' vector with 2 elements (unnamed).
  > stopifnot(is.null(names(y)))
  > with_r_330({
  +   stopifnot(identical(lengths(y), c(0L, 1L)))
  + })
  > 
  > y <- x[-1]
  > print(y)
  A 'listenv' vector with 2 elements (unnamed).
  > stopifnot(is.null(names(y)))
  > with_r_330({
  +   stopifnot(identical(lengths(y), c(0L, 1L)))
  + })
  > 
  > x[c("c", ".a", "b")] <- list(NULL, 3, 1)
  > print(x)
  A 'listenv' vector with 6 elements ('', '', '', ..., 'b').
  > stopifnot(identical(names(x), c("", "", "", "c", ".a", "b")))
  > with_r_330({
  +   stopifnot(identical(lengths(x), c(1L, 0L, 1L, c = 0L, .a = 1L, b = 1L)))
  + })
  > 
  > y <- as.list(x)
  > str(y)
  List of 6
   $   : num 1
   $   : NULL
   $   : num 3
   $ c : NULL
   $ .a: num 3
   $ b : num 1
  > stopifnot(identical(names(y), c("", "", "", "c", ".a", "b")))
  > 
  > y <- as.list(x, all.names = FALSE)
  > str(y)
  List of 5
   $  : num 1
   $  : NULL
   $  : num 3
   $ c: NULL
   $ b: num 1
  > stopifnot(identical(names(y), c("", "", "", "c", "b")))
  > 
  > y <- as.list(x, sorted = TRUE)
  > str(y)
  List of 6
   $   : num 1
   $   : NULL
   $   : num 3
   $ .a: num 3
   $ b : num 1
   $ c : NULL
  > stopifnot(identical(names(y), c("", "", "", ".a", "b", "c")))
  > 
  > y <- as.list(x, all.names = FALSE, sorted = TRUE)
  > str(y)
  List of 5
   $  : num 1
   $  : NULL
   $  : num 3
   $ b: num 1
   $ c: NULL
  > stopifnot(identical(names(y), c("", "", "", "b", "c")))
  > 
  > 
  > x <- listenv()
  > x[c("a", "b", "c")] <- list(1, NULL, 3)
  > 
  > y <- x[NULL]
  > print(y)
  A 'listenv' vector with 0 elements (unnamed).
  > z <- as.list(y)
  > print(z)
  list()
  > stopifnot(identical(z, list()))
  > 
  > y <- x[integer(0L)]
  > print(y)
  A 'listenv' vector with 0 elements (unnamed).
  > z <- as.list(y)
  > print(z)
  list()
  > stopifnot(identical(z, list()))
  > 
  > y <- x["a"]
  > print(y)
  A 'listenv' vector with 1 element ('a').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  > stopifnot(identical(z, list(a = 1)))
  > 
  > y <- x[c("a", "c")]
  > print(y)
  A 'listenv' vector with 2 elements ('a', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $c
  [1] 3
  
  > stopifnot(identical(z, list(a = 1, c = 3)))
  > 
  > y <- x[c("c", "a")]
  > print(y)
  A 'listenv' vector with 2 elements ('c', 'a').
  > z <- as.list(y)
  > print(z)
  $c
  [1] 3
  
  $a
  [1] 1
  
  > stopifnot(identical(z, list(c = 3, a = 1)))
  > 
  > y <- x[c(1, 3)]
  > print(y)
  A 'listenv' vector with 2 elements ('a', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $c
  [1] 3
  
  > stopifnot(identical(z, list(a = 1, c = 3)))
  > 
  > y <- x[-2]
  > print(y)
  A 'listenv' vector with 2 elements ('a', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $c
  [1] 3
  
  > stopifnot(identical(z, list(a = 1, c = 3)))
  > 
  > y <- x[-c(1, 3)]
  > print(y)
  A 'listenv' vector with 1 element ('b').
  > z <- as.list(y)
  > print(z)
  $b
  NULL
  
  > stopifnot(identical(z, list(b = NULL)))
  > 
  > y <- x[rep(1L, times = 6L)]
  > print(y)
  A 'listenv' vector with 6 elements ('a', 'a', 'a', ..., 'a').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $a
  [1] 1
  
  $a
  [1] 1
  
  $a
  [1] 1
  
  $a
  [1] 1
  
  $a
  [1] 1
  
  > stopifnot(identical(z, rep(list(a = 1), times = 6L)))
  > 
  > y <- x[1:10]
  > print(y)
  A 'listenv' vector with 10 elements ('a', 'b', 'c', ..., '').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $b
  NULL
  
  $c
  [1] 3
  
  [[4]]
  NULL
  
  [[5]]
  NULL
  
  [[6]]
  NULL
  
  [[7]]
  NULL
  
  [[8]]
  NULL
  
  [[9]]
  NULL
  
  [[10]]
  NULL
  
  > stopifnot(identical(z, c(as.list(x), rep(list(NULL), times = 7L))))
  > 
  > 
  > y <- x[c(TRUE, FALSE, TRUE)]
  > print(y)
  A 'listenv' vector with 2 elements ('a', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $c
  [1] 3
  
  > stopifnot(identical(z, list(a = 1, c = 3)))
  > 
  > y <- x[c(TRUE, FALSE)]
  > print(y)
  A 'listenv' vector with 2 elements ('a', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $c
  [1] 3
  
  > stopifnot(identical(z, list(a = 1, c = 3)))
  > 
  > y <- x[TRUE]
  > print(y)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $b
  NULL
  
  $c
  [1] 3
  
  > stopifnot(identical(z, as.list(x)))
  > 
  > y <- x[FALSE]
  > print(y)
  A 'listenv' vector with 0 elements (unnamed).
  > z <- as.list(y)
  > print(z)
  list()
  > stopifnot(identical(z, list()))
  > 
  > y <- x[rep(TRUE, times = 5L)]
  > print(y)
  A 'listenv' vector with 5 elements ('a', 'b', 'c', '', '').
  > z <- as.list(y)
  > print(z)
  $a
  [1] 1
  
  $b
  NULL
  
  $c
  [1] 3
  
  [[4]]
  NULL
  
  [[5]]
  NULL
  
  > stopifnot(identical(z, c(as.list(x), list(NULL), list(NULL))))
  > with_r_330({
  +   stopifnot(identical(lengths(z), c(a = 1L, b = 0L, c = 1L, 0L, 0L)))
  + })
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Local access
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv(a = 1, b = 2, c = 3.14)
  > 
  > y <- local({
  +   x[[3]]
  + })
  > stopifnot(identical(y, 3.14))
  > 
  > y <- local({
  +   x[3]
  + })
  > stopifnot(identical(y[[1]], 3.14))
  > 
  > y <- local({
  +   ii <- 3
  +   x[[ii]]
  + })
  > stopifnot(identical(y, 3.14))
  > 
  > y <- local({
  +   ii <- 3
  +   x[ii]
  + })
  > stopifnot(identical(y[[1]], 3.14))
  > 
  > 
  > local({
  +   x[[3]] <- 42L
  + })
  > y <- x[[3]]
  > stopifnot(identical(y, 42L))
  > 
  > local({
  +   x[3] <- 3.14
  + })
  > y <- x[[3]]
  > stopifnot(identical(y, 3.14))
  > 
  > local({
  +   ii <- 3
  +   x[ii] <- 42L
  + })
  > y <- x[[3]]
  > stopifnot(identical(y, 42L))
  > 
  > local({
  +   ii <- 3
  +   x[[ii]] <- 3.14
  + })
  > y <- x[[3]]
  > stopifnot(identical(y, 3.14))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Removing elements
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x[["a"]] <- NULL
  > print(x)
  A 'listenv' vector with 2 elements ('b', 'c').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "b" "c"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("b", "c")))
  > 
  > x[[3L]] <- NULL
  > print(x)
  A 'listenv' vector with 2 elements ('b', 'c').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "b" "c"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("b", "c")))
  > 
  > x[[2L]] <- NULL
  > print(x)
  A 'listenv' vector with 1 element ('b').
  > print(length(x))
  [1] 1
  > print(names(x))
  [1] "b"
  > stopifnot(length(x) == 1)
  > stopifnot(identical(names(x), c("b")))
  > 
  > x$b <- NULL
  > print(x)
  A 'listenv' vector with 0 elements (named).
  > print(length(x))
  [1] 0
  > print(names(x))
  character(0)
  > stopifnot(length(x) == 0)
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Assigning NULL
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x[2L] <- list(NULL)
  > print(x)
  A 'listenv' vector with 2 elements ('', '').
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "" ""
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("", "")))
  > 
  > x["c"] <- list(NULL)
  > print(x)
  A 'listenv' vector with 3 elements ('', '', 'c').
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] ""  ""  "c"
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("", "", "c")))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Assigning multiple elements at once
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > x[c("a", "b", "c")] <- 1:3
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > str(as.list(x))
  List of 3
   $ a: int 1
   $ b: int 2
   $ c: int 3
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] "a" "b" "c"
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "c")))
  > stopifnot(identical(as.list(x), list(a = 1L, b = 2L, c = 3L)))
  > stopifnot(identical(unlist(x), c(a = 1L, b = 2L, c = 3L)))
  > 
  > x[] <- 3:1
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "c")))
  > stopifnot(identical(as.list(x), list(a = 3L, b = 2L, c = 1L)))
  > 
  > x[c("c", "b")] <- 2:3
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > str(as.list(x))
  List of 3
   $ a: int 3
   $ b: int 3
   $ c: int 2
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] "a" "b" "c"
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "c")))
  > stopifnot(identical(as.list(x), list(a = 3L, b = 3L, c = 2L)))
  > 
  > x[c("a", "c")] <- 1L
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > str(as.list(x))
  List of 3
   $ a: int 1
   $ b: int 3
   $ c: int 1
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] "a" "b" "c"
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "c")))
  > stopifnot(identical(as.list(x), list(a = 1L, b = 3L, c = 1L)))
  > 
  > x[c("d", "e")] <- 4:5
  > print(x)
  A 'listenv' vector with 5 elements ('a', 'b', 'c', 'd', 'e').
  > str(as.list(x))
  List of 5
   $ a: int 1
   $ b: int 3
   $ c: int 1
   $ d: int 4
   $ e: int 5
  > print(length(x))
  [1] 5
  > print(names(x))
  [1] "a" "b" "c" "d" "e"
  > stopifnot(length(x) == 5)
  > stopifnot(identical(names(x), c("a", "b", "c", "d", "e")))
  > stopifnot(identical(as.list(x), list(a = 1L, b = 3L, c = 1L, d = 4L, e = 5L)))
  > 
  > 
  > x <- listenv()
  > x[c("a", "b")] <- 1:2
  > x[c(TRUE, FALSE)] <- 2L
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > str(as.list(x))
  List of 2
   $ a: int 2
   $ b: int 2
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(as.list(x), list(a = 2L, b = 2L)))
  > 
  > x[c(TRUE)] <- 1L
  > print(x)
  A 'listenv' vector with 2 elements ('a', 'b').
  > str(as.list(x))
  List of 2
   $ a: int 1
   $ b: int 1
  > print(length(x))
  [1] 2
  > print(names(x))
  [1] "a" "b"
  > stopifnot(length(x) == 2)
  > stopifnot(identical(names(x), c("a", "b")))
  > stopifnot(identical(as.list(x), list(a = 1L, b = 1L)))
  > 
  > x[c(TRUE, FALSE, TRUE, FALSE)] <- 3L
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', '').
  > str(as.list(x))
  List of 3
   $ a: int 3
   $ b: int 1
   $  : int 3
  > print(length(x))
  [1] 3
  > print(names(x))
  [1] "a" "b" "" 
  > stopifnot(length(x) == 3)
  > stopifnot(identical(names(x), c("a", "b", "")))
  > stopifnot(identical(as.list(x), list(a = 3L, b = 1L, 3L)))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Removing multiple elements at once
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- as.listenv(1:6)
  > names(x) <- letters[seq_along(x)]
  > y <- as.list(x)
  > stopifnot(identical(as.list(x), y))
  > 
  > x[2] <- NULL
  > y[2] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > x[4:3] <- NULL
  > y[4:3] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > x[rep(2, times = 10)] <- NULL
  > y[rep(2, times = 10)] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > ## Erase all elements
  > y[] <- NULL
  > x[] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > x <- as.listenv(1:6)
  > names(x) <- letters[seq_along(x)]
  > y <- as.list(x)
  > stopifnot(identical(as.list(x), y))
  > 
  > # Every other by logical indexing
  > x[c(TRUE, FALSE)] <- NULL
  > y[c(TRUE, FALSE)] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > x[c("b", "f")] <- NULL
  > y[c("b", "f")] <- NULL
  > stopifnot(identical(as.list(x), y))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Expanding
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > for (ii in 1:3) {
  +   x[[ii]] <- letters[ii]
  +   print(x[[ii]])
  + }
  [1] "a"
  [1] "b"
  [1] "c"
  > print(x)
  A 'listenv' vector with 3 elements (unnamed).
  > names(x) <- sprintf("item%d", seq_along(x))
  > print(x)
  A 'listenv' vector with 3 elements ('item1', 'item2', 'item3').
  > 
  > y <- as.list(x)
  > str(y)
  List of 3
   $ item1: chr "a"
   $ item2: chr "b"
   $ item3: chr "c"
  > stopifnot(identical(names(y), c("item1", "item2", "item3")))
  > stopifnot(identical(y[[1]], "a"), identical(y[[2]], "b"),
  +           identical(y[[3]], "c"))
  > x[[2]] <- "B"
  > stopifnot(identical(x$item2, "B"))
  > 
  > 
  > x <- listenv()
  > x[[1]] <- { 1 }
  > x[[3]] <- { "Hello world!" }
  > stopifnot(length(x) == 3)
  > stopifnot(identical(seq_along(x), seq_len(length(x))))
  > print(x)
  A 'listenv' vector with 3 elements (unnamed).
  > names(x) <- c("a", "b", "c")
  > print(x)
  A 'listenv' vector with 3 elements ('a', 'b', 'c').
  > x$b <- TRUE
  > stopifnot(identical(x[[1]], 1))
  > stopifnot(identical(x[[2]], TRUE))
  > stopifnot(identical(x$b, TRUE))
  > stopifnot(identical(x[["b"]], TRUE))
  > y <- as.list(x)
  > str(y)
  List of 3
   $ a: num 1
   $ b: logi TRUE
   $ c: chr "Hello world!"
  > stopifnot(length(y) == 3)
  > 
  > 
  > ## Mixed names and indices
  > x <- listenv()
  > x$a <- 1
  > x[[3]] <- 3
  > print(names(x))
  [1] "a" ""  "" 
  > stopifnot(identical(names(x), c("a", "", "")))
  > 
  > # First element (should be named "a")
  > var <- get_variable(x, "a")
  > stopifnot(var == "a")
  > var <- get_variable(x, 1)
  > stopifnot(var == "a")
  > 
  > # Third element (should be a temporary name)
  > var <- get_variable(x, 3)
  > stopifnot(var != "c")
  > names(x) <- c("a", "b", "c")
  > var <- get_variable(x, 3)
  > stopifnot(var != "c")
  > var <- get_variable(x, "c")
  > stopifnot(var != "c")
  > 
  > ## Second element (should become "b", because it was never used
  > #                  before it was "named" "b")
  > x$b <- 2
  > var <- get_variable(x, 2)
  > stopifnot(var == "b")
  > var <- get_variable(x, "b")
  > stopifnot(var == "b")
  > 
  > 
  > ## Names where as.integer(names(x)) are integers
  > x <- listenv()
  > x[["1"]] <- 1
  > x[["3"]] <- 3
  > print(names(x))
  [1] "1" "3"
  > stopifnot(identical(names(x), c("1", "3")))
  > 
  > 
  > ## Expand and shrink
  > x <- listenv()
  > stopifnot(length(x) == 0L)
  > length(x) <- 3L
  > stopifnot(length(x) == 3L)
  > stopifnot(is.null(names(x)))
  > 
  > names(x) <- c("a", "b", "c")
  > x$a <- 2
  > stopifnot(identical(x$a, 2))
  > x[c("a", "c")] <- c(2, 1)
  > stopifnot(identical(x$a, 2), identical(x$c, 1))
  > 
  > length(x) <- 4L
  > stopifnot(length(x) == 4L)
  > stopifnot(identical(names(x), c("a", "b", "c", "")))
  > 
  > length(x) <- 1L
  > stopifnot(length(x) == 1L)
  > stopifnot(identical(names(x), c("a")))
  > stopifnot(identical(x$a, 2))
  > 
  > length(x) <- 0L
  > stopifnot(length(x) == 0L)
  > stopifnot(length(names(x)) == 0) # Actually, character(0), cf. lists
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Flatten
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > for (recursive in c(FALSE, TRUE)) {
  +   x <- list(); x$a <- list(B = 1:3); x$b <- list(C = 1:3, D = 4:5)
  +   y1 <- unlist(x, recursive = recursive)
  + 
  +   x <- listenv(); x$a <- list(B = 1:3); x$b <- list(C = 1:3, D = 4:5)
  +   y2 <- unlist(x, recursive = recursive)
  +   stopifnot(identical(y2, y1))
  + } # for (recursive ...)
  > 
  > x <- listenv(); x$a <- list(B = 1:3); x$b <- as.listenv(list(C = 1:3, D = 4:5))
  > y3 <- unlist(x, recursive = TRUE)
  > stopifnot(identical(y3, y1))
  > 
  > x <- listenv()
  > y <- unlist(x)
  > stopifnot(length(y) == 0)
  > stopifnot(is.null(y))
  > 
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Comparisons
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv(c = NULL, .a = 3, b = 1)
  > print(x)
  A 'listenv' vector with 3 elements ('c', '.a', 'b').
  > 
  > ## A list environment is always equal to itself
  > stopifnot(all.equal(x, x))
  > 
  > ## List environments emulate lists
  > stopifnot(all.equal(x, list(c = NULL, .a = 3, b = 1)))
  > stopifnot(all.equal(x, list(c = NULL, .a = 3, b = 1), sorted = TRUE))
  > stopifnot(all.equal(x, list(.a = 3, b = 1, c = NULL), sorted = TRUE))
  > 
  > stopifnot(all.equal(x, list(c = NULL, b = 1), all.names = FALSE))
  > stopifnot(all.equal(x, list(.a = 3, c = NULL, b = 1), all.names = FALSE))
  > stopifnot(all.equal(x, list(b = 1, c = NULL), all.names = FALSE, sorted = TRUE))
  > 
  > res <- all.equal(x, list(b = 1, c = NULL), sorted = FALSE)
  > stopifnot(!isTRUE(res))
  > 
  > res <- all.equal(x, list(b = 1, c = NULL), all.names = FALSE)
  > stopifnot(!isTRUE(res))
  > 
  > ## Assert listenv() -> as.list() -> as.listenv() equality
  > y <- as.list(x)
  > stopifnot(identical(names(y), names(x)))
  > z <- as.listenv(y)
  > stopifnot(identical(names(z), names(y)))
  > stopifnot(all.equal(x, y))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Warnings
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > x[1:3] <- 1:3
  > res <- tryCatch(x[1:2] <- 1:4, warning = function(w) {
  +   class(w) <- "try-warning"
  +   w
  + })
  > stopifnot(inherits(res, "try-warning"))
  > 
  > res <- tryCatch(x[1:3] <- 1:2, warning = function(w) {
  +   class(w) <- "try-warning"
  +   w
  + })
  > stopifnot(inherits(res, "try-warning"))
  > 
  > res <- tryCatch(x[integer(0L)] <- 1, warning = function(w) {
  +   class(w) <- "try-warning"
  +   w
  + })
  > stopifnot(!inherits(res, "try-warning"))
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Exception handling
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > x <- listenv()
  > length(x) <- 3L
  > names(x) <- c("a", "b", "c")
  > 
  > res <- try(names(x) <- c("a", "b"), silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[1:2]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[0]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[length(x) + 1]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[1 + 2i]], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[1 + 2i], silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[1 + 2i]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[1 + 2i] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[integer(0L)]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[1:2]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[Inf]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[0]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[-1]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[character(0L)]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[c("a", "b")]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(x[[""]] <- 1, silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > 
  > ## Cleanup
  > options(oopts)
  > rm(list = setdiff(ls(envir = globalenv()), ovars), envir = globalenv())
  > 
  > proc.time()
     user  system elapsed 
     0.31    0.04    0.36 
Running the tests in 'tests/parse_env_subset,dimensions.R' failed.
Complete output:
  > library("listenv")
  > 
  > ovars <- ls(envir = globalenv())
  > if (exists("x")) rm(list = "x")
  > if (exists("y")) rm(list = "y")
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Multi-dimensional subsetting
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - -
  > message("*** parse_env_subset() on multi-dim listenv ...")
  *** parse_env_subset() on multi-dim listenv ...
  > 
  > x <- listenv()
  > length(x) <- 6
  > dim(x) <- c(2, 3)
  > 
  > target <- parse_env_subset(x[2], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 1
    ..$ : num 2
   $ idx   : num 2
   $ exists: logi FALSE
   $ code  : chr "x[2]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx  == 2, !target$exists)
  > 
  > target <- parse_env_subset(x[[2]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 1
    ..$ : num 2
   $ idx   : num 2
   $ exists: logi FALSE
   $ code  : chr "x[[2]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx  == 2, !target$exists)
  > 
  > target <- parse_env_subset(x[1, 2], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 2
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] FALSE
   $ code  : chr "x[1, 2]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, !target$exists)
  > 
  > target <- parse_env_subset(x[[1, 2]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 2
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] FALSE
   $ code  : chr "x[[1, 2]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, !target$exists)
  > 
  > x[[1, 2]] <- 1.2
  > target <- parse_env_subset(x[1, 2], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 2
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] TRUE
   $ code  : chr "x[1, 2]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, target$exists)
  > 
  > target <- parse_env_subset(x[[1, 2]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 2
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] TRUE
   $ code  : chr "x[[1, 2]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, target$exists)
  > 
  > target <- parse_env_subset(x[1, 4], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 4
   $ idx   : num [1, 1] NA
   $ exists: logi [1, 1] FALSE
   $ code  : chr "x[1, 4]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), is.na(target$idx), !target$exists)
  > 
  > target <- parse_env_subset(x[[1, 4]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 4
   $ idx   : num [1, 1] NA
   $ exists: logi [1, 1] FALSE
   $ code  : chr "x[[1, 4]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), is.na(target$idx), !target$exists)
  > 
  > target <- parse_env_subset(x[1, 1:2], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 2
    ..$ : num 1
    ..$ : int [1:2] 1 2
   $ idx   : num [1, 1:2] 1 3
   $ exists: logi [1, 1:2] FALSE TRUE
   $ code  : chr "x[1, 1:2]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x),
  +           length(target$idx) == 2L, all(target$idx == c(1,3)),
  + 	  length(target$exists) == 2L, all(target$exists == c(FALSE, TRUE)))
  > 
  > target <- parse_env_subset(x[1, -3], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num -3
   $ idx   : num [1, 1:2] 1 3
   $ exists: logi [1, 1:2] FALSE TRUE
   $ code  : chr "x[1, -3]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x),
  +           length(target$idx) == 2L, all(target$idx == c(1,3)),
  + 	  length(target$exists) == 2L, all(target$exists == c(FALSE, TRUE)))
  > 
  > ## Assert that x[[1, 4]] is not the same as x[[c(1, 4)]]
  > target <- parse_env_subset(x[[1, 4]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : num 1
    ..$ : num 4
   $ idx   : num [1, 1] NA
   $ exists: logi [1, 1] FALSE
   $ code  : chr "x[[1, 4]]"
   $ name  : chr ""
  > target2 <- parse_env_subset(x[[c(1, 4)]], substitute = TRUE)
  > str(target2)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
   $ op    : chr "[["
   $ subset:List of 1
    ..$ : num [1:2] 1 4
   $ idx   : num [1:2] 1 4
   $ exists: logi [1:2] FALSE FALSE
   $ code  : chr "x[[c(1, 4)]]"
   $ name  : chr ""
  > target$code <- target2$code <- NULL
  > stopifnot(!isTRUE(all.equal(target2, target)))
  > 
  > 
  > dimnames(x) <- list(c("a", "b"), c("A", "B", "C"))
  > print(x)
  A 'listenv' matrix with 6 elements (unnamed) arranged in 2x3 rows ('a', 'b') and columns ('A', 'B', 'C').
  > 
  > target <- parse_env_subset(x[["a", 2]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : num 2
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] TRUE
   $ code  : chr "x[[\"a\", 2]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, target$exists)
  > 
  > target <- parse_env_subset(x[["a", "B"]], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "[["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : chr "B"
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] TRUE
   $ code  : chr "x[[\"a\", \"B\"]]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, target$exists)
  > 
  > target <- parse_env_subset(x["a", "B"], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : chr "B"
   $ idx   : num [1, 1] 3
   $ exists: logi [1, 1] TRUE
   $ code  : chr "x[\"a\", \"B\"]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), target$idx == 3, target$exists)
  > 
  > target <- parse_env_subset(x["a", 1:3], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : int [1:3] 1 2 3
   $ idx   : num [1, 1:3] 1 3 5
   $ exists: logi [1, 1:3] FALSE TRUE FALSE
   $ code  : chr "x[\"a\", 1:3]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), length(target$idx) == 3,
  +           all(target$idx == c(1, 3, 5)),
  +           all(target$exists == c(FALSE, TRUE, FALSE)))
  > 
  > target <- parse_env_subset(x["a", ], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : NULL
   $ idx   : num [1, 1:3] 1 3 5
   $ exists: logi [1, 1:3] FALSE TRUE FALSE
   $ code  : chr "x[\"a\", ]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), length(target$idx) == 3,
  +           all(target$idx == c(1, 3, 5)),
  +           all(target$exists == c(FALSE, TRUE, FALSE)))
  > 
  > target <- parse_env_subset(x["a", -1], substitute = TRUE)
  > str(target)
  List of 7
   $ envir :Classes 'listenv', 'environment' <environment: 0x000001f63db6c530> 
    ..- attr(*, "dim.")= int [1:2] 2 3
    ..- attr(*, "dimnames.")=List of 2
    .. ..$ : chr [1:2] "a" "b"
    .. ..$ : chr [1:3] "A" "B" "C"
   $ op    : chr "["
   $ subset:List of 2
    ..$ : chr "a"
    ..$ : num -1
   $ idx   : num [1, 1:2] 3 5
   $ exists: logi [1, 1:2] TRUE FALSE
   $ code  : chr "x[\"a\", -1]"
   $ name  : chr ""
  > stopifnot(identical(target$envir, x), length(target$idx) == 2,
  +           all(target$idx == c(3, 5)),
  +           all(target$exists == c(TRUE, FALSE)))
  > 
  > message("*** parse_env_subset() on multi-dim listenv ... DONE")
  *** parse_env_subset() on multi-dim listenv ... DONE
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## Exception handling
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - -
  > message("*** parse_env_subset() on multi-dim listenv - exceptions ...")
  *** parse_env_subset() on multi-dim listenv - exceptions ...
  > 
  > x <- listenv()
  > 
  > ## Multidimensional subsetting on 'x' without dimensions
  > res <- try(target <- parse_env_subset(x[[1, 2]], substitute = TRUE),
  +            silent = TRUE)
  > stopifnot(inherits(res, "try-error"))
  > 
  > ## Multi-dimensional subsetting
  > x <- listenv()
  > length(x) <- 6
  > dim(x) <- c(2, 3)
  > 
  > 
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > ## FIXME: Should zero indices give parse errors or not?
  > ## - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > res <- try(target <- parse_env_subset(x[[0]], substitute = TRUE), silent = TRUE)
  > ## stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(target <- parse_env_subset(x[[1, 0]], substitute = TRUE),
  +            silent = TRUE)
  > ## stopifnot(inherits(res, "try-error"))
  > 
  > res <- try(target <- parse_env_subset(x[[1, 2, 3]], substitute = TRUE),
  +            silent = TRUE)
  > ## stopifnot(inherits(res, "try-error"))
  > 
  > message("*** parse_env_subset() on multi-dim listenv - exceptions ... DONE")
  *** parse_env_subset() on multi-dim listenv - exceptions ... DONE
  > 
  > 
  > ## Cleanup
  > rm(list = setdiff(ls(envir = globalenv()), ovars), envir = globalenv())
  > 
  > proc.time()
     user  system elapsed 
     0.28    0.06    0.32 
Running the tests in 'tests/utils.R' failed.
Complete output:
  > printf <- function(...) cat(sprintf(...))
  > hpaste <- listenv:::hpaste
  > 
  > # Some vectors
  > x <- 1:6
  > y <- 10:1
  > z <- LETTERS[x]
  > 
  > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > # Abbreviation of output vector
  > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > printf("x = %s.\n", hpaste(x))
  x = 1, 2, 3, ..., 6.
  > ## x = 1, 2, 3, ..., 6.
  > 
  > printf("x = %s.\n", hpaste(x, max_head = 2))
  x = 1, 2, ..., 6.
  > ## x = 1, 2, ..., 6.
  > 
  > printf("x = %s.\n", hpaste(x, max_head = 3)) # Default
  x = 1, 2, 3, ..., 6.
  > ## x = 1, 2, 3, ..., 6.
  > 
  > # It will never output 1, 2, 3, 4, ..., 6
  > printf("x = %s.\n", hpaste(x, max_head = 4))
  x = 1, 2, 3, 4, 5, 6.
  > ## x = 1, 2, 3, 4, 5 and 6.
  > 
  > # Showing the tail
  > printf("x = %s.\n", hpaste(x, max_head = 1, max_tail = 2))
  x = 1, ..., 5, 6.
  > ## x = 1, ..., 5, 6.
  > 
  > # Turning off abbreviation
  > printf("y = %s.\n", hpaste(y, max_head = Inf))
  y = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1.
  > ## y = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
  > 
  > ## ...or simply
  > printf("y = %s.\n", paste(y, collapse = ", "))
  y = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1.
  > ## y = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
  > 
  > 
  > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > # Adding a special separator before the last element
  > # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  > # Change last separator
  > printf("x = %s.\n", hpaste(x, last_collapse = " and "))
  x = 1, 2, 3, 4, 5 and 6.
  > ## x = 1, 2, 3, 4, 5 and 6.
  > 
  > proc.time()
     user  system elapsed 
     0.15    0.09    0.21