Metaclass deligate is not an instance

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

User.metaClass.dynamicAttributes = [:]

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

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

But it fails, and I step on my patience!

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! 
0
source share
2 answers

change of this

User.metaClass.dynamicAttributes = [:]

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

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

to that

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
}

I decided! I'm not sure, but it seems that groovy is sharing an attribute placed through metaClass!

0
source

The problem is that your concept is completely corrupted. You assign a map to a class, not an instance with this line:

User.metaClass.dynamicAttributes = [:]

To accomplish what you are looking for, 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 
}

, , , , .

+1

All Articles