【问题标题】:How can I pass a class to Groovy's Eval binding?如何将类传递给 Groovy 的 Eval 绑定?
【发布时间】:2014-10-07 17:02:57
【问题描述】:

我正在做一些严重的事情,比如使用 Groovy 的 metaClass 和 Eval 从 XML 导入中为对象动态分配属性:

class ObjectBuilder {
  def assignProp(String propName, String propValue) {
    Eval.x(this, "x.metaClass.${propName} = '${propValue}'")     
  }
}

def h = new ObjectBuilder()
h.assignProp('name', 'Henson')
println(h.name)

不过,我想做的是能够在其内部实例化该类的另一个副本:

Eval.x(this, "x.metaClass.${ObjName} = new ObjectBuilder()")

但我不能,因为我认为该类没有传递给绑定。还有其他解决方案吗?

【问题讨论】:

  • 你想做什么?你能提供更多的背景信息吗?您有一个 XML,您从中解析出一个对象并尝试向其中添加一个动态属性?或者它是来自Xml{Parser|Builder}Node?为什么要实例化ObjectBuilder?主要目标是什么?
  • 嘿@WillP,我想我学到的东西比什么都多;-) 我正在做的是阅读 XML,但我想基于它创建一个对象,使用我的规范作为字符串传入(我只想要 XML 中的一些内容,并且采用不同的结构。)这部分正是我尝试动态构建对象的地方。

标签: grails groovy groovyshell


【解决方案1】:

几个解决方案:

展开

您可以尝试使用一堆Expandos

h = new Expando()
h.last = new Expando()
h.last.name = 'tech'

assert h.last.name == 'tech'

直接对对象进行元分类

xml = '''
<person>
  <name>john</name>
  <surname>doe</surname>
  <age>41</age>
  <location>St Louis, MO</location>
</person>
'''

class Person {
  def name, surname, location, age
}

root = new XmlParser().parseText xml

person = new Person(root.children().collectEntries { [it.name(), it.text()] })

person.metaClass.getFullname = { "$delegate.name $delegate.surname" }

assert person.fullname == "john doe"

person.metaClass.likes = "chicken with lemon"

assert person.likes == "chicken with lemon" 

地图

map = [:]
map.last = [:]
map.last.name = 'Tech'
assert map.last.name == 'Tech'

【讨论】:

  • 嗯,这太棒了!如果 XML 类似于..&lt;names&gt;&lt;name&gt;Henson&lt;/name&gt;&lt;name&gt;Will&lt;/name&gt;&lt;/names&gt;,您是否见过任何模式?我有一些深度数据,包含数组。
  • @techHenson 你应该在你的问题中使用嵌套结构发布你的 XML
【解决方案2】:

传递一个新实例化的对象,然后用 Eval 分配它似乎可行:

class ObjectBuilder {
  def assignProp(String propName, String propValue) {
    Eval.x(this, "x.metaClass.${propName} = '${propValue}'")     
  }
  def nestObj(String objName) {
    Eval.xy(this, new ObjectBuilder(), "x.metaClass.${objName} = y")
  }
}

ObjectBuilder h = new ObjectBuilder()
h.assignProp('name', 'Henson')
h.nestObj('last')
h.last.assignProp('name', 'Tech')

println h.name + ' ' + h.last.name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    相关资源
    最近更新 更多