Skip to content

Infix attr accessor #69

Closed
Closed

Description

@hadley

Maybe purrr would be a good place for:

`%@%` <- function(x, name) attr(x, name)

Need to think about if this should be S3 generic or not, and need to check if this works as is for S4.

Activity

  1. lionel- commented on Apr 28, 2015

    @lionel-
    Member

    I've always been frustrated that @ does not work as an attribute accessor... Especially since Kevin Ushey mentioned on twitter that S4 slots are actually attributes.

    I suppose it would be highly inappropriate to force the matter and export a redefinition?

    `@` <- function(x, slot) {
      slot <- as.character(substitute(slot))
    
      if (isS4(x)) {
        env <- new.env(parent = parent.frame())
        env$`@` <- base::`@`
        eval(call("@", x, slot), envir = env)
      } else {
        attr(x, slot)
      }
    }
    
    mtcars@names
  2. hadley commented on Apr 28, 2015

    @hadley
    MemberAuthor

    Yeah, we can't override existing functions, so I think %@% is the best we can do. It might be worth trying to push upstream to R core though.

  3. npjc commented on May 10, 2015

    @npjc

    would this follow then?

    x %@% "foo" <- "bar"    # attr(x,"foo") <- "bar"     // x.attr("foo") = "bar";

    OR use %<@% analogous to the %<>% relationship %>%

    if so then what of

    attributes(x) <- list(mycomment = "really special", foo = 3:2,bar = paste(1:6))
    x %<@% list(mycomment = "really special", foo = 3:2,bar = paste(1:6))

    then you need an .append = TRUE or such...

  4. lionel- commented on May 10, 2015

    @lionel-
    Member

    The first one works:

    `%@%` <- attr
    `%@%<-` <- `attr<-`
    
    mtcars %@% "names"
    mtcars %@% "names" <- 1:11

    The idea of overloading these operators to work with lists seems interesting.

    `%@%` <- function(x, slots) {
      if (length(slots) > 1) {
        attributes(x)[slots]
      } else {
        attr(x, slots)
      }
    }
    
    `%@%<-` <- function(x, slots, value) {
      if (length(slots) > 1) {
        attributes(x)[slots] <- value
        x
      } else {
        attr(x, slots) <- value
      }
    }
    
    mat <- as.matrix(mtcars)
    mat %@% c("dimnames", "dim")
    mat %@% c("dimnames", "dim") <- list(NULL, c(2, 16, 11))

    But it's not good to have the output type change as a function of the number of slots requested. So we'd have to choose one of those two behaviours. The most useful is the list of attributes accessor probably, and we can still hope that R core will enable single attribute lookup with @ in the future :)

  5. lionel- commented on May 10, 2015

    @lionel-
    Member

    it's not good to have the output type change as a function of the number of slots requested.

    One possibility is to make the behaviour depend on whether the slot is a vector or a list. But the syntax becomes kind of heavy then

    mat %@% list("dimnames", "dim") <- list(NULL, c(2, 16, 11))
  6. hadley commented on Sep 24, 2015

    @hadley
    MemberAuthor

    I'd rather keep it simple and stick with just getting of single values.

  7. hadley commented on Nov 11, 2015

    @hadley
    MemberAuthor

    Closed in 97ddec7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions