local()
puede implementar un patrón singleton - por ejemplo, el paquete snow
utiliza esto para realizar un seguimiento de la instancia única RMPI que el usuario podría crear.
getMPIcluster <- NULL
setMPIcluster <- NULL
local({
cl <- NULL
getMPIcluster <<- function() cl
setMPIcluster <<- function(new) cl <<- new
})
local()
también podrían utilizarse para gestionar la memoria en una secuencia de comandos, por ejemplo, la asignación de grandes objetos intermedios necesarios para crear un objeto final en la última línea de la cláusula. Los objetos intermedios grandes están disponibles para la recolección de basura cuando devuelve local
.
El uso de una función para crear un cierre es un patrón de fábrica: el ejemplo bank account en la documentación de Introducción a R, donde cada vez que se invoca open.account
, se crea una nueva cuenta.
Como @otsaw menciones, memoization podría ser implementado utilizando local, por ejemplo, a los sitios web de caché en un rastreador
library(XML)
crawler <- local({
seen <- new.env(parent=emptyenv())
.do_crawl <- function(url, base, pattern) {
if (!exists(url, seen)) {
message(url)
xml <- htmlTreeParse(url, useInternal=TRUE)
hrefs <- unlist(getNodeSet(xml, "//a/@href"))
urls <-
sprintf("%s%s", base, grep(pattern, hrefs, value=TRUE))
seen[[url]] <- length(urls)
for (url in urls)
.do_crawl(url, base, pattern)
}
}
.do_report <- function(url) {
urls <- as.list(seen)
data.frame(Url=names(urls), Links=unlist(unname(urls)),
stringsAsFactors=FALSE)
}
list(crawl=function(base, pattern="^/.*html$") {
.do_crawl(base, base, pattern)
}, report=.do_report)
})
crawler$crawl(favorite_url)
dim(crawler$report())
(el ejemplo usual de memoization, los números de Fibonacci, no es satisfactoria - la gama de números que no se desbordan La representación numérica de R es pequeña, por lo que uno probablemente usaría una tabla de búsqueda de valores precalculados de manera eficiente). Interesante cómo el rastreador aquí es un singleton; podría haber seguido tan fácilmente un patrón de fábrica, por lo que un rastreador por URL base.
Otro patrón que 'local' hace conveniente es la memorización. Hay un ejemplo en algún lugar de The R Inferno. – otsaw
Su idea de que crawler sea singleton es interesante porque una alternativa a lo local es evaluar inmediatamente una función anónima sin argumentos: un patrón de fábrica podría utilizar un cierre sobre la url base. – hadley