问题
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