-
Notifications
You must be signed in to change notification settings - Fork 853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
增加调用对象方法的功能 #169
Comments
这个方法不适用,表达式是通过配置配置进去的,程序会给表达式传递上下文参数,将所有可能需要的实例对象都传递给上下文作为表达式的参数,表达式里面根据传递的对象要进行一些对象方法的引用处理(其中还会用到其他对象的属性值),此时对于程序来说表达式到底会用到哪些实例是未知的,只有运行时加载了表达式才知道,所以不可能提前导入,下面是我debug源码以后加了补丁的代码,你看一下: import java.lang.reflect.Field; import com.googlecode.aviator.exception.FunctionNotFoundException; /**
*/ @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide @OverRide private final String name; RuntimeFunctionDelegator(String name) { @OverRide private AviatorFunction getFunc(Map<String, Object> env, AviatorObject ...args) {
} public Class[] fetchTypes(Map env, Object[] args){
Class[] parameterTypes = new Class<?>[args.length]; public Object delegateInvoke(Map<String, Object> env, Object object, String methodName, Object[] args) throws Exception { public class DelegateFunction implements AviatorFunction{
} } |
另外就是有很多call的定义,为什么不集成到一起,通过动态参数的方式只弄一个call呢,对于固定参数个数的call,顶多做一下参数个数的判断,这样岂不是更好一些,这样定义一堆感觉很累赘 |
这样的应用场景并不是 aviator 设计的初衷,aviator 本质上是希望能控制允许使用的方法,类似一个沙箱。你可以继续用补丁的方式。_ |
至于为什么定义多个 call,主要是性能考虑。 你的场景可以考虑直接继承 AbstractVariadicFunction,实现一个方法即可 |
实际上大部分人可能用不上我说的功能,但是如果有需要的则会变得很方便,增加这个功能对原有的使用方式也不会有性能的影响,仅仅是建议,目前我的应用只能是先用这种源码补丁的方式处理,至于继承 AbstractVariadicFunction,有时间了看看怎么处理,目前对各个类的关系还不是很清晰,如何继承还不是很清楚,不过还是要谢谢你的回复 |
从我个人角度是不大推荐采用修改源码的方式,因为后续升级都会很困难,一些 bug 修复或者新特性没办法及时跟上。 你这里的需求,理论上可以通过提供一个 interface MethodMissing {
void onMethodMissing(String name, Map<String, Object> env, AviatorObject...args);
} 这个接口的实现,就可以将你的定制逻辑放进去,而不用去修改源码,你认为呢? 为什么不加入自动导入的方式,核心原因前面也提过了, aviator 希望整个求值使用到的方法和函数都是受控的,不是用户想执行就能执行什么,这里有安全和管控的因素在。 |
这个建议的机制不错,我看看怎么通过实现这个做到我想要的能力,实际上我也是没有发现更好的方式而不得已用了修改源码的方式进行处理,我比较了一些表达式的库,相比较而言,你写的这套还是比较优秀的。 |
已经加了个 issue #170 , 这个实现还是比较容易的,我会抓紧搞定下。 后续发布后,建议你再修改。 |
好的,这种跟进速度超赞 |
已实现,可以参考这个 PR #171 看看是否可以满足你的要求。 |
好的,我看看 |
看了实现过程,这样可以实现对象的方法调用,如果是对象的属性的方法(多级的那种,a.b.c.fun(xx)这种),貌似就不行了:) |
不过这种机制提供了一个可扩展的机制,可以自己实现一个FunctionMissing,做那种深度遍历的处理,也算是可以解决了:) |
@lixinlin 嵌套正常调用应该是 |
a对象的b属性对象的c属性对象的fun,这种,例如表达式:obja.objb.objc.funx(yy)+5 |
@lixinlin 我明白你的意思。 aviator 支持 a.b.c 这样的语法糖的,他可以获取 a 的 b 属性的 c 属性。因此上述调用可以改成 |
这里主要的差异在于 aviator 的方法调用都是 dot 可以做变量的嵌套访问,参见 所以理论上这个 PR 可以替代你原来的实现的,只是需要改下调用方式,非常不推荐采用 |
这个语法有点怪,那参数怎么传递?method(a.b.c, arg1, arg2)这种形式? |
@lixinlin 是的,内置函数和通过导入的方法都是这种方式 |
绕了一圈竟然是用法上的问题:) |
@lixinlin 4.2.5 已经发布,理论上你可以无缝替换使用了,只是需要改下表达式。 参见 |
ok |
如果表达式中引用了环境变量里面的对象,需要在表达式里能够调用这个对象的方法执行一些处理
The text was updated successfully, but these errors were encountered: