proto <- function (. = parent.env(envir), expr = {}, envir =
new.env(parent = parent.frame()), ..., funEnvir = envir) {
parent.env(envir) <- .
as.proto.environment(envir) # must do this before eval(...)
# moved eval after for so that ... always done first
# eval(substitute(eval(quote({ expr }))), envir)
dots <- list(...); names <- names(dots)
for (i in seq(length = length(dots))) {
assign(names[i], dots[[i]], env = envir)
if (!identical(funEnvir, FALSE) && is.function(dots[[i]]))
environment(envir[[names[i]]]) <- funEnvir
}
eval(substitute(eval(quote({ expr }))), envir)
if (length(dots)) as.proto.environment(envir) else envir
}
as.proto <- function(x, ...) UseMethod("as.proto")
as.proto.environment <- function(x, ...) {
assign(".that", x, env = x)
assign(".super", parent.env(x), env = x)
structure(x, class = c("proto", "environment"))
}
as.proto.proto <- function(x, ...) x
as.proto.list <- function(x, envir, parent, all.names = FALSE, ...,
funEnvir = envir, SELECT = function(x) TRUE) {
if (missing(envir)) {
if (missing(parent)) parent <- parent.frame()
envir <- if (is.proto(parent))
parent$proto(...)
else
proto(parent, ...)
}
for(s in names(x))
if (SELECT(x[[s]])) {
assign(s, x[[s]], env = envir)
if (is.function(x[[s]]) && !identical(funEnvir, FALSE))
environment(envir[[s]]) <- funEnvir
}
if (!missing(parent)) parent.env(envir) <- parent
as.proto.environment(envir) # force refresh of .that and .super
}
# "$.proto" <- function(this, x) {
# inh <- substr(x,1,2) != ".."
# p <- parent.frame()
# is.function <- is.function(get(x, env = this, inherits = inh))
# is.that <- match(deparse(substitute(this)), c(".that",".super"), nomatch=0)
# s <- if (is.function && !is.that)
# substitute(function(...) get(x, env = this, inherits = inh)(this, ...))
# else
# substitute(get(x, env = this, inherits = inh))
# res <- eval(s, list(inh = inh), p)
# if (is.function && !is.that) environment(res) <- p
# res
# }
"$<-.proto" <- function(this,s,value) {
if (s == ".super") parent.env(this) <- value
if (is.function(value)) environment(value) <- this
this[[as.character(substitute(s))]] <- value
this
}
is.proto <- function(x) inherits(x, "proto")
isnot.function <- function(x) ! is.function(x)
"$.proto" <-
function (this, x, args) {
inh <- substr(x, 1, 2) != ".."
p <- parent.frame()
res <- get(x, env = this, inherits = inh)
is.function <- is.function(res)
is.that <- match(deparse(substitute(this)), c(".that", ".super"),
nomatch = 0)
if (is.function && !is.that) {
res <- function(...) get(x, env = this, inherits = inh)(this, ...)
class(res) <- c("instantiatedProtoMethod", "function")
attr(res, "this") <- this
if (!missing(args)) res <- do.call(res, args, envir = p)
}
res
}
# modified from Tom Short's original
print.instantiatedProtoMethod <- function(x, ...) {
# cat("proto method call: ")
# print(unclass(x))
cat("proto method (instantiated with ", name.proto(attr(x, "this")),
"): ", sep = "")
print(eval(body(x)[[1]]))
}
# modified from Tom Short's original
str.proto <- function(object, max.level = 1, nest.lev = 0, indent.str =
paste(rep.int(" ", max(0, nest.lev + 1)), collapse = ".."), ...) {
cat("proto", name.proto(object), "\n")
Lines <- capture.output(str(as.list(object), max.level = max.level,
nest.lev = nest.lev, ...))[-1]
for(s in Lines) cat(s, "\n")
if (is.proto(parent.env(object))) {
cat(indent.str, "parent: ", sep = "")
str(parent.env(object), nest.lev = nest.lev + 1, ...)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.