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 | Show 2 more comments2 Answers
Reset to default 5You 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
attr(myclosure, 'closure_attribute') <- 'foo'
. – Axeman Commented Feb 7 at 0:20"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