如何迭代 groovy 类非静态闭包并选择性地替换它们?

发布于 2024-12-05 08:03:06 字数 397 浏览 1 评论 0原文

我想迭代 groovy 类非静态闭包并可选择替换它们。

我可以使用类似的方法获取 MetaClass

MyClassName.metaClass

,从那里我可以获取所有属性,例如

metaClassObject.properties

MetaProperty 对象的列表。

问题是我无法检测哪些属性是闭包,哪些是简单对象。在这两种情况下,MetaProperty 对象的类型属性都返回 Object。

关于替换:比方说,我知道它是一个闭包 A,那么我可以创建另一个闭包 B,用一些可选代码包装闭包 A,并在类定义中用 B 替换该闭包 A 吗?应该像某种拦截器一样工作。

I'd like to iterate over groovy class non-static closures and optionally replace them.

I can get MetaClass with something like

MyClassName.metaClass

and from there I can get all properties like

metaClassObject.properties

which is the list of MetaProperty objects.

The problem is that I can't detect which of those properties are closures and which are simple objects. MetaProperty object's type property return Object in both case.

And about replacing: Let's say, I know that it is a closure A, then can I create another closure B that wraps closure A with some optional code and replace that closure A with B in the class definition? Should work like some sort of interceptor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疯到世界奔溃 2024-12-12 08:03:06

这是我尝试过的一种方法:

class Test {
  def name = 'tim'

  def processor = { str ->
    "Hello $name $str"
  }
}

Test t = new Test()

t.metaClass.properties.each {
  if( t[ it.name ].metaClass.respondsTo( it, 'doCall' ) ) {
    println "$it.name is a closure"
    def old = t[ it.name ]
    t.metaClass[ it.name ] = { str ->
      "WOO! ${old( str )}"
    }
  }
}

println t.processor( 'groovy!' ) // prints 'WOO! Hello tim groovy!'

但是,它需要扩展,因为我依赖于这样一个事实:我知道修补闭包替换需要多少个参数

也可能有一种更简单的方法来做到这一点......

This is one way I have tried out:

class Test {
  def name = 'tim'

  def processor = { str ->
    "Hello $name $str"
  }
}

Test t = new Test()

t.metaClass.properties.each {
  if( t[ it.name ].metaClass.respondsTo( it, 'doCall' ) ) {
    println "$it.name is a closure"
    def old = t[ it.name ]
    t.metaClass[ it.name ] = { str ->
      "WOO! ${old( str )}"
    }
  }
}

println t.processor( 'groovy!' ) // prints 'WOO! Hello tim groovy!'

However, it would need expanding as I rely on the fact that I know how many parameters it takes for the patching closure replacement

There may also be a simpler way to do this...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文