robject

Is there an R class which allows to list 2 elements but shows only the first of them by default when called?


I am writing a function for ciphering small phrases, and I end up having the initial phrase (w0) and its encrypted version (w1).

I would like to enter both w0 and w1 into an object which is returned by the function, and I am currently doing it using list()

However, if I save it in an object (called TEST in the code) and then call it, both the initial and the encrypted phrase are print, which is not optimal for me.

I would like to have the possibility to save the output in an object which, when called naively, will only show the first element (the initial word), with the possibility to print the second one when required specifically, maybe using $.

Is this possible? Thanks!

My current function with list()

cipher <- function(word){

  w0 <- tolower(unlist(strsplit(word, "")))
  w1 <- c()
  shuffledletters <- sample(letters)
  
  for (i in (1:length(w0))) {
    w1[i] <- ifelse(w0[i] %in% letters,
                    shuffledletters[which(w0[i]==letters)], " ")
  }

out <- list(w0,w1)
return(out)
}

What I get now:

TEST <- cipher("hello world")
TEST

[[1]]
 [1] "h" "e" "l" "l" "o" " " "w" "o" "r" "l" "d"

[[2]]
 [1] "p" "s" "r" "r" "a" " " "y" "a" "j" "r" "m"

What I would like to have as output (I know that with lists this is not possible)

TEST
 [1] "h" "e" "l" "l" "o" " " "w" "o" "r" "l" "d"

TEST$initial
 [1] "h" "e" "l" "l" "o" " " "w" "o" "r" "l" "d"

TEST$encrypted
 [1] "p" "s" "r" "r" "a" " " "y" "a" "j" "r" "m"


Solution

  • This seems like a good example to create your own class (see ?class), with a custom print method. For example:

    cipher <- function(word){
    
      w0 <- tolower(unlist(strsplit(word, "")))
      w1 <- c()
      shuffledletters <- sample(letters)
      
      for (i in (1:length(w0))) {
        w1[i] <- ifelse(w0[i] %in% letters,
                        shuffledletters[which(w0[i]==letters)], " ")
      }
    
    out <- list(initial=w0,encrypted=w1)
    class(out) <- "cipher"
    return(out)
    }
    
    print.cipher <- function(x,...){
      print.default(x$initial, ...)
    }
    
    TEST <- cipher("hello world")
    
    TEST
    # [1] "h" "e" "l" "l" "o" " " "w" "o" "r" "l" "d"
    
    TEST$initial
    # [1] "h" "e" "l" "l" "o" " " "w" "o" "r" "l" "d"
    
    TEST$encrypted
    # [1] "s" "d" "x" "x" "r" " " "g" "r" "a" "x" "p"