Get all sourced functions
It's a bit clunky but you could look at changes in the objects before and after the source
call like this.
# optionally delete all variables
#rm(list=ls())
before <- ls()
cat("f1 <- function(){}\nf2 <- function(){}\n", file = 'define_function.R')
# defines these
#f1 <- function() {}
#f2 <- function() {}
source('define_function.R')
after <- ls()
changed <- setdiff(after, before)
changed_objects <- mget(changed, inherits = T)
changed_function <- do.call(rbind, lapply(changed_objects, is.function))
new_functions <- changed[changed_function]
new_functions
# [1] "f1" "f2"
I think that this regex catches almost every valid type of function (binary operator, assignment functions) and every valid character in a function name, but I may have missed an edge case.
# lines <- readLines("functions.R")
lines <- c(
"`%in%` <- function",
"foo <- function",
"foo2bar <- function",
"`%in%`<-function",
"foo<-function",
".foo <-function",
"foo2bar<-function",
"`foo2bar<-`<-function",
"`foo3bar<-`=function",
"`foo4bar<-` = function",
"` d d` <- function",
"lapply(x, function)"
)
grep("^`?%?[.a-zA-Z][._a-zA-Z0-9 ]+%?(<-`)?`?\\s*(<-|=)\\s*function", lines)
#> [1] 1 2 3 4 5 6 7 8 9 10
funs <- grep("^`?%?[.a-zA-Z][._a-zA-Z0-9 ]+%?(<-`)?`?\\s*(<-|=)\\s*function", lines, value = TRUE)
gsub("^(`?%?[.a-zA-Z][._a-zA-Z0-9 ]+%?(<-`)?`?).*", "\\1", funs)
#> [1] "`%in%`" "foo " "foo2bar " "`%in%`" "foo"
#> [6] ".foo " "foo2bar" "`foo2bar<-`" "`foo3bar<-`" "`foo4bar<-`"
I think the best way would be to source the file into a temporary environment. Query that environment for all the functions, then copy those values to the parent environment.
my_source <- function(..., local=NULL) {
tmp <- new.env(parent=parent.frame())
source(..., local = tmp)
funs <- names(tmp)[unlist(eapply(tmp, is.function))]
for(x in names(tmp)) {
assign(x, tmp[[x]], envir = parent.frame())
}
list(functions=funs)
}
my_source("script.R")