【问题标题】:Metaclass deligate not being instance元类委托不是实例
【发布时间】:2014-12-05 09:05:30
【问题描述】:

我有这个代码存根来添加动态属性。我使用 mongodb,我想动态添加属性。这是我在单元测试时尝试做的。

User.metaClass.dynamicAttributes = [:]

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

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

但这失败了,我正在超越我的耐心极限!

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! 

【问题讨论】:

    标签: mongodb unit-testing grails metaclass


    【解决方案1】:

    这里的问题是你的概念完全有缺陷。您正在将地图分配给 Class 而不是带有此行的实例:

    User.metaClass.dynamicAttributes = [:]
    

    为了完成您想要做的事情,您需要执行以下操作:

    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 
    }
    

    我确信有一种更简洁的方法可以做到这一点,但上面演示了一个解决方案,其中地图是按实例而不是所有实例进行实例化的。

    【讨论】:

    • 你的意思是,它是一个实例属性,但所有实例都受到影响?
    • 这是一个 StackOverflowError!它循环第一个条件!
    • 得到了答案!编辑你的答案
    【解决方案2】:

    改变这个

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

    到这里

    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
    }
    

    解决了!我不确定,但似乎 groovy 共享 metaClass 中的属性!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多