Metaclass deligate not being instance

霸气de小男生 提交于 2019-12-13 04:49:40

问题


I have this stub of code to add dynamic attributes. I work with mongodb and i want to add the properties dynamically. This is what i tried to do when unit testing.

User.metaClass.dynamicAttributes = [:]

User.metaClass.propertyMissing = { String name ->
    delegate.dynamicAttributes[name]
}

User.metaClass.propertyMissing = { String name, value ->
    delegate.dynamicAttributes[name] = value
}

But this fails and i am stepping over my patience limit!

User u = new User()
u.ppt = 0

User u2 = new User()
u2.ppt = 1

assert u2.ppt == 1
assert u.ppt == 0 // fails here, println shows that u.ppt is also 1! 

回答1:


The issue here is that your concept is completely flawed. You are assigning a map to the Class and not the instance with this line:

User.metaClass.dynamicAttributes = [:]

In order to accomplish what you are looking to do you need to do the following:

User.metaClass.propertyMissing = { String name ->
  if (!delegate.dynamicAttributes) delegate.dynamicAttributes = [:]
  delegate.dynamicAttributes[name] 
}  
User.metaClass.propertyMissing = { String name, value ->     
  if (!delegate.dynamicAttributes) delegate.dynamicAttributes = [:]
  delegate.dynamicAttributes[name] = value 
}

I'm sure there is a cleaner way to do this but the above demonstrates a solution where the map is instanced per instance and not across all instances.




回答2:


changing this

User.metaClass.dynamicAttributes = [:]

User.metaClass.propertyMissing = { String name ->
    delegate.dynamicAttributes[name]
}

User.metaClass.propertyMissing = { String name, value ->
    delegate.dynamicAttributes[name] = value
}

to this

User.metaClass.propertyMissing = { String name ->
    if (!delegate.metaClass.hasProperty('dynamicAttributes') delegate.metaClass.dynamicAttributes = [:]
    delegate.dynamicAttributes[name]
}

User.metaClass.propertyMissing = { String name, value ->
    if (!delegate.metaClass.hasProperty('dynamicAttributes') delegate.metaClass.dynamicAttributes = [:]
    delegate.dynamicAttributes[name] = value
}

Solved it! I am not sure, but it seems like groovy shares the attribute put through metaClass!



来源:https://stackoverflow.com/questions/27312245/metaclass-deligate-not-being-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!