如何将对象的元类还原为原始类定义 [英] How to restore metaclass on object to original class definition

查看:94
本文介绍了如何将对象的元类还原为原始类定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图在新对象上创建TEMPORARY覆盖,然后删除对象本身上的覆盖.我不确定是否可以做到这一点,但这是我到目前为止已经尝试过的方法.

I've been trying to create a TEMPORARY override on new objects, and then to remove the override on the objects themselves. I'm not sure if this can be done, but here is what I've tried so far.

// Say I have a class like:
class Validator {
  boolean validate() { println "code here to return actual true/false"; false }
}

// I have two integration points one of them is Here before construction:

// First integration point:
// Save actual validate function
def realValidate = Validator.&validate
// Make new instances of Validator have the validate function hardwired to true
Validator.metaClass.validate { -> println "hardwired true"; true }

// Code I'd rather not modify
// Now some code executes which news up an instance and calls validate
def validator = new Validator()
validator.validate() // This correctly calls our override

// Second integration point.
// Without newing up a new Validator object, I'd like to remove the override.
Validator.metaClass = null

validator.metaClass.validate = Validator.&validate

// This throws "java.lang.IllegalArgumentException: object is not an instance of declaring class"
//validator.validate()

// So maybe I have to explicitly say:
realValidate.resolveStrategy = Closure.DELEGATE_FIRST

// But this still throws the same exception
//validator.validate()

// Perhaps if I tell my objects metaclass to forget about validate, it will bubble up and look for the method on its declaring class?
validator.metaClass.validate = { -> throw new MissingMethodException("validate", Validator.class, (Object[])[], false) }

// This throws MissingMethodException: No signature of method: Validator.validate() is applicable for argument types: () values: []
//  Possible solutions: validate(), wait()
//validator.validate()

抱歉,没有一个超级具体的问题,因为我不知道在这个特定领域中有什么可能.我既喜欢我的代码无法正常工作的原因,也喜欢让它正常工作的替代方法.

Apologies for not having a super specific question, since I don't know what all is possible in this particular area. I'd love both the reason why my code doesn't work, as well as alternatives to make it work.

推荐答案

这可能是每个实例元类的问题... Validator.metaClass = null会将Validator类的全局元类设置为默认值.但是这里的验证器实例是Groovy类,因此在实例本身中存储了对meta类的单独引用.用该实例进行的调用将不会通过全局元类的查找,而是使用每个实例元类(存储在实例本身中的引用).因此,validator.metaClass = null是重置此设置的唯一方法

This could be a per instance meta class problem... Validator.metaClass = null will set the global meta class for the Validator class to default. but your validator instance here is a Groovy class and thus stores a separate reference to the meta class in the instance itself. Calls with that instance will not go through a lookup of the global meta class and instead use the per instance meta class (the reference stored in the instance itself). Thus validator.metaClass = null is the only way to reset this

这篇关于如何将对象的元类还原为原始类定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆