有没有办法在 eval 中调用 class 方法?
Is there a way to call a class method inside an eval?
我正在编写 Groovy 粘贴到基于 Web 的系统中的脚本 运行。有一个
class 可用于此环境中的脚本 运行,我称之为 BrokenClass
。它有一个
错误,它只接受字符串文字作为其第一个参数,而不接受变量
里面有一个字符串。所以,这会起作用(它 returns 一个列表):
BrokenClass.reflist('something', 'name')
但是,如果我尝试使用变量作为第一个参数,则会出现错误:
list_name = 'something'
BrokenClass.reflist(list_name, 'name')
这会生成消息 Metadata RefList[something] cannot be accessed
。
我无法控制 BrokenClass(除了在其上提交错误)。我试着工作
围绕这样的问题:
list_name = "foo"
list_call = "BrokenClass.reflist(${list_name}, 'name')"
list_values = Eval.me(list_call)
但是,这会产生错误:
groovy.lang.MissingPropertyException: No such property: BrokenClass for class: Script1
我尝试将 import
添加到我的字符串中,但后来我得到 unable to resolve class BrokenClass
.
有没有办法在 eval 字符串中使用 BrokenClass
?或者我没有的其他方式
是否考虑解决 BrokenClass.reflist
中的错误?一个很长的 switch
块
已经出来了,因为可能的列表名称发生了变化。
BrokenClass.reflist
的方法签名是:
public static List<Object> reflist(String reflistName, String field);
我怀疑 BrokenClass.reflist()
使用 == 运算符而不是 String.equals()
直接或间接地进行不正确的字符串比较。有关差异的解释,请参阅 this 文章。
问题
下面是问题的演示:
def a = 'whatever'
def b = 'what' + 'ever'
assert doSomething('whatever') == 'OK'
assert doSomething(a) == 'OK'
assert doSomething(b) == 'ERROR'
def doSomething(String value) {
if(value.is('whatever')) { // In Java this would be: value == "whatever"
'OK'
} else {
'ERROR'
}
}
因为它使用引用相等性,在 Groovy 中由 Object.is(Object)
方法完成,BrokenClass.reflist()
无意中编码为仅适用于字符串文字:所有字符串文字具有相同的value 引用相同的 String 实例,导致计算结果为 True。在 运行 时间组成的具有相同文字值的 String 不引用相同的 String 实例。
解决方法
显然 BrokenClass.reflist()
应该修复。但是您可以使用 interned String.
解决此问题
def b = 'what' + 'ever'
assert doSomething(b.intern()) == 'OK'
def doSomething(String value) {
if(value.is('whatever')) {
'OK'
} else {
'ERROR'
}
}
如果变量的值与字符串文字的值匹配,则 variable.intern()
将 return 与匹配文字相同的字符串实例。这将允许 Java == 运算符按照您的需要工作。
我正在编写 Groovy 粘贴到基于 Web 的系统中的脚本 运行。有一个
class 可用于此环境中的脚本 运行,我称之为 BrokenClass
。它有一个
错误,它只接受字符串文字作为其第一个参数,而不接受变量
里面有一个字符串。所以,这会起作用(它 returns 一个列表):
BrokenClass.reflist('something', 'name')
但是,如果我尝试使用变量作为第一个参数,则会出现错误:
list_name = 'something'
BrokenClass.reflist(list_name, 'name')
这会生成消息 Metadata RefList[something] cannot be accessed
。
我无法控制 BrokenClass(除了在其上提交错误)。我试着工作 围绕这样的问题:
list_name = "foo"
list_call = "BrokenClass.reflist(${list_name}, 'name')"
list_values = Eval.me(list_call)
但是,这会产生错误:
groovy.lang.MissingPropertyException: No such property: BrokenClass for class: Script1
我尝试将 import
添加到我的字符串中,但后来我得到 unable to resolve class BrokenClass
.
有没有办法在 eval 字符串中使用 BrokenClass
?或者我没有的其他方式
是否考虑解决 BrokenClass.reflist
中的错误?一个很长的 switch
块
已经出来了,因为可能的列表名称发生了变化。
BrokenClass.reflist
的方法签名是:
public static List<Object> reflist(String reflistName, String field);
我怀疑 BrokenClass.reflist()
使用 == 运算符而不是 String.equals()
直接或间接地进行不正确的字符串比较。有关差异的解释,请参阅 this 文章。
问题
下面是问题的演示:
def a = 'whatever'
def b = 'what' + 'ever'
assert doSomething('whatever') == 'OK'
assert doSomething(a) == 'OK'
assert doSomething(b) == 'ERROR'
def doSomething(String value) {
if(value.is('whatever')) { // In Java this would be: value == "whatever"
'OK'
} else {
'ERROR'
}
}
因为它使用引用相等性,在 Groovy 中由 Object.is(Object)
方法完成,BrokenClass.reflist()
无意中编码为仅适用于字符串文字:所有字符串文字具有相同的value 引用相同的 String 实例,导致计算结果为 True。在 运行 时间组成的具有相同文字值的 String 不引用相同的 String 实例。
解决方法
显然 BrokenClass.reflist()
应该修复。但是您可以使用 interned String.
def b = 'what' + 'ever'
assert doSomething(b.intern()) == 'OK'
def doSomething(String value) {
if(value.is('whatever')) {
'OK'
} else {
'ERROR'
}
}
如果变量的值与字符串文字的值匹配,则 variable.intern()
将 return 与匹配文字相同的字符串实例。这将允许 Java == 运算符按照您的需要工作。