在调用之前更改和添加方法的参数

时间:2015-06-01 16:00:48

标签: groovy metaprogramming

我想通过拦截对某些方法的调用来重现默认参数的行为。当没有参数调用方法 display 时,以下代码尝试给出默认参数:

with = FALSE

然而,这不起作用;没有任何争论时,什么也没有打印出来。

这个例子不是很有用,但我想让它工作;我的下一个目标确实是创建方法,其参数可以在其名称中给出。例如:

NN <- 10000L
MM <- 100L
mm <- 10L

DT = data.table(id = 1:NN)
DT[ , paste0("col", 1:MM) := lapply(integer(MM), function(x) runif(NN))]

sdcols = function(...) DT[ , .SD, .SDcols = paste0("col", sample(MM, size = mm))]
m.get = function(...) DT[ , mget(paste0("col", sample(MM, size=mm)))]
withF = function(...) DT[ , paste0("col", sample(MM, size = mm)), with = FALSE]

library(microbenchmark)
microbenchmark(times=100L, sdcols(), m.get(), withF())
# Unit: microseconds
#      expr      min        lq      mean    median        uq      max neval cld
#  sdcols()  780.201  810.4350  865.3564  827.4970  853.4875 2354.577   100 a  
#   m.get() 2792.293 2864.1225 3052.3872 2899.9370 3031.9260 4831.963   100   c
#   withF()  897.822  927.7105 1005.3166  945.9495  981.0580 2600.445   100  b 

拦截对这些不存在的方法的调用并调用现有的方法,使用不存在的方法名称中使用的数字进行添加将使其成为可能......

1 个答案:

答案 0 :(得分:4)

班级Thing应实施以下GroovyInterceptable以使invokeMethod有效:

class Thing implements GroovyInterceptable {
    void display(String text) {
        println(text)
    }

    def invokeMethod(String name, args) {
        if(name == "display" && args.length == 0) {
            metaClass.getMetaMethod(name).invoke(this, "some text")
        } else {
            metaClass.getMetaMethod(name, args).invoke(this, args)
        }
    }
}

Thing thing = new Thing()
thing.display("stuff") //prints "stuff"
thing.display()