aviatorscript icon indicating copy to clipboard operation
aviatorscript copied to clipboard

增加 in 运算符支持

Open tangyang9464 opened this issue 3 years ago • 21 comments

see: #208

in 运算符检查右侧数组以查看它是否包含等于左侧值的值。 相等性由 == 运算符的使用确定。 比如

表达式 sub.Name in (obj.Admins)
数据 sub{Name: "alice"}, obj{Name: "a book", Admins: {"alice", "bob"}}

感谢!

tangyang9464 avatar Jul 07 '21 08:07 tangyang9464

用现有函数就支持的,不需要引入特殊的操作符:

seq.some(obj.Admins, fn(x) { x.Name == sub.Name})

killme2008 avatar Jul 07 '21 09:07 killme2008

@killme2008 我尝试使用seq.some(obj.Admins, fn(x) { x.Name == sub.Name}),但似乎编译时识别不了obj.Admins这种形式,只能识别Admins。我不知道它能不能自动获取obj对象中的Admins属性?

tangyang9464 avatar Jul 14 '21 08:07 tangyang9464

我编译可以的,你确定不行吗?

    Expression result =
        AviatorEvaluator.compile("seq.some(obj.Admins, fn(x) { x.Name == sub.Name})");
    System.out.println(result);

输出:

Script_1626251523203_58/824318946@377dca04

killme2008 avatar Jul 14 '21 08:07 killme2008

@killme2008 编译不会直接抛出异常,但debug会显示异常,且结果不正确,我做了一个例子你看一下

class Sub{
    public String Name;
}
class Admins{
    public String Name;
}
class Obj{
    public Admins[] Admins;
}
Sub sub = new Sub();
sub.Name="alice";
Obj obj = new Obj();
Admins admin1 = new Admins();
admin1.Name="alice";
Admins admin2 = new Admins();
admin2.Name = "bob";
Admins[] admins = new Admins[]{admin1,admin2};
obj.Admins=admins;

//obj.Admins,编译不会抛出异常,但debug会显示f0-Method threw 'com.googlecode.aviator.exception.ExpressionRuntimeException' exception. Cannot evaluate com.googlecode.aviator.runtime.type.AviatorJavaType.toString()
Expression ex = AviatorEvaluator.compile("seq.some(obj.Admins, fn(x) {x.Name == sub.Name})");
System.out.println(ex);
Map<String,Object> map = new HashMap<>();
map.put("sub",sub);
map.put("obj",obj);
//o 为null
Object o = ex.execute(map);

//改为Admins,不会显示异常
Expression ex2 = AviatorEvaluator.compile("seq.some(Admins, fn(x) {x.Name == sub.Name})");
System.out.println(ex2);
Map<String,Object> map2 = new HashMap<>();
map2.put("sub",sub);
map2.put("Admins",admins);
//结果正常,查出来o2 为alice
Object o2 = ex2.execute(map2);

tangyang9464 avatar Jul 14 '21 08:07 tangyang9464

请实现 getter/setter

killme2008 avatar Jul 14 '21 09:07 killme2008

请实现 getter/setter

ok,看起来是个低级错误,不好意思。被debug变量显示的异常误导了

tangyang9464 avatar Jul 14 '21 09:07 tangyang9464

这里我看了下,按理说应该报错的,似乎将异常吞没了,原来设定是抛一个 property not found 的异常,我检查下。

不过 public field 似乎是可以支持下的,减少 getter/setter 的繁琐代码。

目前这个 dot 语法糖支持的是 getter/setter 或者 java.util.Map#get ,以及 List 和数组的 get(i)

killme2008 avatar Jul 14 '21 09:07 killme2008

ok,我没有考虑dot这个语法糖的实现方式,默认认为了public可以访问。但为什么第二个例子中sub.name却能访问,也没有getter,第二个例子却能得到正确结果

tangyang9464 avatar Jul 14 '21 09:07 tangyang9464

是因为两个取值都是 null 了,你把 admin 的数组调换下顺序,结果就是 bob 了。这是个陷阱,抛异常是更合理的。

killme2008 avatar Jul 14 '21 09:07 killme2008

已在 5.2.7 分支修复,谢谢反馈

https://github.com/killme2008/aviatorscript/pull/396/commits/ac3122fa670db29a38ff6214c894d0605a26ecea

killme2008 avatar Jul 14 '21 09:07 killme2008

当时测试考虑了应该把alice放后面,后来忽略了。谢谢持续关注,我的问题应该能解决了

tangyang9464 avatar Jul 14 '21 09:07 tangyang9464

@killme2008 不好意思,还有一个问题。现在我用obj.Admins,无论有无getter,debug都会有异常,但可以得到正确结果。你刚才说这里应该抛出异常,但如果这样,我就无法正#常使用了,请问这里你是如何修复更新的

tangyang9464 avatar Jul 14 '21 09:07 tangyang9464

没有 getter 是不可能得到正确值的,目前的反射实现是基于 getter

killme2008 avatar Jul 14 '21 12:07 killme2008

debug 异常是另一个问题,会单独修复

killme2008 avatar Jul 14 '21 12:07 killme2008

计划引入 in 操作符

killme2008 avatar Jul 25 '21 13:07 killme2008

计划引入 in 操作符

考虑将('alice','bob')这种形式识别为数组吗?配合in使用,比如 alice in (alice,bob),我们的项目有这种需求

tangyang9464 avatar Jul 25 '21 13:07 tangyang9464

不会,不准备搞集合的 literal 语法,你需要自己加下函数调用 alice in tuple(alice, bob)

killme2008 avatar Jul 25 '21 13:07 killme2008

不会,不准备搞集合的 literal 语法,你需要自己加下函数调用 alice in tuple(alice, bob)

那期待in的原生支持

tangyang9464 avatar Jul 25 '21 13:07 tangyang9464

用现有函数就支持的,不需要引入特殊的操作符:

seq.some(obj.Admins, fn(x) { x.Name == sub.Name})

这里我也短路了,也不需要用闭包,默认用 include 函数就可以了:

include(obj.Admins, sub.Name);

killme2008 avatar Jul 26 '21 08:07 killme2008

@killme2008 请问这个支持实现了吗?还是又删除了?

tangyang9464 avatar Aug 06 '21 06:08 tangyang9464

@tangyang9464 在现有代码上的实现会有缺陷,暂时放弃了,还是先准备做大版本重构。

killme2008 avatar Aug 06 '21 09:08 killme2008