对带有无效密钥的DSL使用groovy映射
我目前正在构建一个小的DSL,它需要指定key = value对中的一组属性,但是这些密钥可能包含破折号' - '或句点''。我似乎无法让它工作。对带有无效密钥的DSL使用groovy映射
煮沸我本质上尝试传递一个Map作为委托给一个闭包,但是这个语法一直让我着迷。
作为一个例子,考虑这样的:
def map = [:]
map.with {
example1 = 123
//exam-ple2 = 123
//'exam-ple3' = 123
//(exam-ple4) = 123
exam.ple5 = 123
//'exam.ple6' = 123
}
实施例1是精细,关键字等于值和容易读取。例2和例4是编译器根据二进制表达式编译的。例3和例6是常量表达式,不会被编译。例5将编译,但在运行时生成一个NPE。
我可以使用变通方法,例如将Map作为参数传递给闭包,这给了我例3和例6,但是它的冗长让我很烦恼。
有没有人有任何想法如何整齐地DSL属性映射?
BTW:我从Java调用不是常规的DSL,所以在分析方面的技巧必须是java :)
更新1:在inital意见和答案后..
所以脚本由GroovyShell评估为DelegatingScript,其中代表是Java对象。封闭包含来自.properties
文件的属性,需要在不同的上下文中进行定义,例如,
env {
server-name=someHost1
database.name=someHost2
clientName=someHost3
}
委派(Java)的对象将读取该块,作为
public void env(Closure closure) {
Map map = new HashMap();
closure.setDelegate(map);
closure.setResolveStrategy(Closure.DELEGATE_ONLY);
closure.call();
... do something with map...
}
现在的用户(即不是我)可能会从原来的属性文件复制到脚本更改名称,因此我宁愿他们可以做到这一点,而不必编辑太多,因为它肯定会导致错别字。
正如我所说我也有例3和6海湾红色为好,但肯定的,蒂姆,我忘了隐含的吧:)
现在我已经改变了格式的字符串,因此DSL使用多写像
env '''
server-name=someHost1
database.name=someHost2
clientName=someHost3
'''
也就是说,直插式字符串而不是关闭,然后读取字符串,并使用标准的java.util.Properties:
public void env(String envString) {
Properties properties = new Properties;
properties.load(new StringReader(envString))
....etc
}
虽然这个工程,具有封闭和M的组合最后一行字符串是目前唯一的缺点。
在地图声明,Groovy中解析标识符,比如example1
和example2
为字符串键到地图:
[ example1: 1, example2: 2 ]
在.with{}
情况下,它可能使用setProperty(property, value)
机制。
但你的案件的特点表现exam.ple
和exam-ple
。这些表达式有优先权,因此,Groovy会尝试先解决它们(可能分别类似于exam.getProperty('ple')
和exam.minus(ple)
)。
你有一些语法的替代品,但你必须要清楚,以常规什么都应该是字符串键,什么是其他表达式:
def map = [
'exam.ple4' : 4, // direct map declaration
example5 : 5 // unambiguous key declaration: no quotes needed
]
map.with {
example1 = 1
put 'exam.ple2', 2 // ambiguous, needs quotes
it.'exam-ple3' = 3 // as per @TimYates suggestion
}
assert map['exam-ple3'] == 3
assert map.'exam.ple2' == 2
assert map['exam.ple4'] == 4
assert map.example5 == 5 // again, no quotes needed for key
你可以这样解释:“解析方必须是java'? 由于内部groovy DSL依赖groovy语法分析器 像地图元素分配这里,你将如何解析它与Java? 如果你打电话groovy,无论如何不会在groovy方面做到这一点? – ARA
'it.'exam-ple2'= 123' –