Loggerの引数にRの式そのまま書けるようにしたいなあと思った。そういうのって他にどういう関数があったかなあと思ったらsystem.timeがまさにそんな感じ。関数の定義を読む。
system.time <- function(expr, gcFirst = TRUE) { ppt <- function(y) { if(!is.na(y[4])) y[1] <- y[1] + y[4] if(!is.na(y[5])) y[2] <- y[2] + y[5] y[1:3] } if(!exists("proc.time")) return(rep(NA_real_, 5)) if(gcFirst) gc(FALSE) time <- proc.time() ## need on.exit after 'time' has been set: ## on some systems proc.time throws an error. on.exit(cat("Timing stopped at:", ppt(proc.time() - time), "\n")) expr # evaluated here because of lazy evaluation new.time <- proc.time() on.exit() structure(new.time - time, class="proc_time") }
コメントしてあるところに「# evaluated here because of lazy evaluation」とある。つまり、exprで式だけ持っておいて、そこまでその式を評価しない。つまり遅延評価をすることで、色々できそうである、ということが判明。そういえばRの基本となるオブジェクトにexpressionというのがあったなあと思い出すなどした。そういうわけでこういうことができることが分かった。
> (function(exp){exp})(print("hoge")) [1] "hoge"
ほえー。
Further Reading
- R Language Definition
- p2のオブジェクトの種類についての説明
- 「expression 表現式オブジェクト」
- p4の表現式オブジェクトのところ
- 言語オブジェクトとの違いについて
- p32の表現式オブジェクトの評価のところ
- p2のオブジェクトの種類についての説明