最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to add properties to closures in R? - Stack Overflow

programmeradmin2浏览0评论

I need to add properties to all closures... All closures lookup properties from a global environment set at startup. I tried implementing

`$.closure` <- function(obj, prop) {
  #prop lookup code here
}

and

`$<-.closure` <- function(obj, prop, value) {
   #prop setup in global env
}

But it is silently ignored :-( And when I try to use an expression like
aBlock <- function() print("hello")

aBlock$value()  

The error stops saying in Spanish :-P

Error en aBlock$value: objeto de tipo 'closure' no es subconjunto

What I am ommiting (or need to implement) to set the accessors for closures?

I need to add properties to all closures... All closures lookup properties from a global environment set at startup. I tried implementing

`$.closure` <- function(obj, prop) {
  #prop lookup code here
}

and

`$<-.closure` <- function(obj, prop, value) {
   #prop setup in global env
}

But it is silently ignored :-( And when I try to use an expression like
aBlock <- function() print("hello")

aBlock$value()  

The error stops saying in Spanish :-P

Error en aBlock$value: objeto de tipo 'closure' no es subconjunto

What I am ommiting (or need to implement) to set the accessors for closures?

Share Improve this question edited Feb 7 at 19:39 aleReimondo asked Feb 6 at 23:15 aleReimondoaleReimondo 1711 gold badge1 silver badge7 bronze badges 7
  • Closures are not subsettable, as the error suggests.. What are you actually trying to do? Are you looking for a type system? You can set attributes.. e.g. attr(myclosure, 'closure_attribute') <- 'foo'. – Axeman Commented Feb 7 at 0:20
  • 1 "closure" is a type and not a class. There is class "function" but that includes functions with type "special" (primitive and internal functions etc.), which your method would need to handle. – Roland Commented Feb 7 at 7:35
  • 2 This could be an XY problem. – Limey Commented Feb 7 at 9:49
  • @Axeman I am trying to handle closures as any other thing in R. I mean, use closure as any other value (as first class value). That way, the code we write can be the same and not demanding to be a closure what is named by a variable name. – aleReimondo Commented Feb 7 at 15:32
  • @Roland the same happens for function, it is silently ignored the implementation for '$.function' – aleReimondo Commented Feb 7 at 15:32
 |  Show 2 more comments

2 Answers 2

Reset to default 5

You can't do what you tried, because the S3 system for objects without "class" attributes is fairly inconsistent. Some types work, some don't.

However, you can always assign a class to a closure, and then dispatch on that class. It will only work for functions with that class, but that might be enough.

For example:

f <- function(x) print(x)

class(f) <- "newclass"

`$.newclass` <- function(x, y) attr(x, y)

f$class
#> [1] "newclass"

Created on 2025-02-06 with reprex v2.1.1

Questions posted to SO need to be reproducible which means that others can copy and paste your code to their session to see the same result you see.

That said, you can't subset a function in R. This gives the same error.

f <- function(x) log(x)
f$a
## Error in f$a : object of type 'closure' is not subsettable

Functions can have attributes which can be set and extracted using attr<- and attr as indicated in a comment. Using f defined above

f(5)
## [1] 1.609438

attr(f, "data") <- 3
attr(f, "data")
## [1] 3

You can also add comments to functions.

comment(f) <- "Hello":

comment(f)
## [1] "Hello"

or you can create an object with both functions and data by using lists or environments.

myObj <- list(fun = log, data = 3)

myObj$fun(5)
## [1] 1.609438


myObj$data
## [1] 3

To set an attribute on all current functions in a specific environment

attr_funs <- function(envir = .GlobalEnv, attribute, value) {
  for(nm in ls(envir))
    if (is.function(envir[[nm]]))
      attr(envir[[nm]], attribute) <- value
}

# test
L <- local({ f <- \(x) x; Bod <- BOD; environment() })
attr_funs(L, "a", 3)
as.list(L)

giving:

$Bod
  Time demand
1    1    8.3
2    2   10.3
3    3   19.0
4    4   16.0
5    5   15.6
6    7   19.8

$f
\(x) x
<environment: 0x000002121ed0dd60>
attr(,"a")
[1] 3
发布评论

评论列表(0)

  1. 暂无评论