Another question: I need the last statement in scr...
# scripting
a
Another question: I need the last statement in script to be returned as result. Is it possible to do it?
Solved the problem by declaring a base class with nullable
result
field and wrapping the script with
"result = run{$this}"
i
a
yeah, my workaround works fine. I managed to run few tests as they are intended to. I wander if the JSR-223 or REPL API has any advantages compared to scripting API. The later seems to be more convenient for custom classpath and external imports, but maybe there some costs for it?
i
REPL API is still unofficial and hopefully will be replaced soon with something similar to the scripting API. JSR-223 is a standard one, but lack many customization-related scripting features yet. This will be addressed relatively soon. In general, if you don’t need REPL interactivity and JSR-223 compatibility, new scripting seem the preferable way to go.
a
Could you explain what do you mean by "REPL interactivity"? We are talking about notebook environment. It is very similar to REPL, but we probalby want to cache generated code for each cell in future.
i
Notebook sounds like a REPL for me. In this case it is probably a bit early to port it to scripting, otherwise you’ll need to implement a somewhat complicated logic on top of the script compiler and evaluator to emulate “REPL-iness”, i.e. a declarations sharing between snippets. We’re going to do it eventually in the scripting infrastructure and offer a sane API for that, so maybe it is better to wait a bit.
a
OK, thanks, I will study it a bit further.
s
Hi all! I had a similar question to @altavir about fetching the return value from a script. While his workaround is OK for basic use cases, some other things don’t work when you add a “result=run{ … }” wrapper around the script (for example, you seemingly lose the ability for your script to hoist functions up, so you can no longer override methods in the base class). I am guessing there is nothing that can be done about this until KT-28137 is implemented? With that having been said, if I had to choose one API to use for a new project, is the new/“experimental” KEEP-75 API likely to be the most stable? JSR223 won’t be sufficient for our needs, and the comments in this thread make it sound like the existing REPL API is internal-only and likely to change significantly anyway?
i
@Scott Dudley Current REPL API should be considered internal, yes, and unfortunately it is still unclear how much time it will take to prepare a new REPL API compatible with KEEP-75. But I’m curious - what is not sufficient for you in JSR-223?
And yes, the KT-28137 is the right way to implement the return value. Again, unfortunately I cannot give estimates now. It is not something very big, but there are many more important things in the pipeline.
s
I admit that I’m not 100% confident that JSR223 would not work, but in general, the goal is to be able to execute untrusted code with some semblance of security. I know that this is complicated and not all problems are solvable (ie. DoS via resource consumption), but we need to prevent at least unauthorized access. Some issues are: • we will need to tightly control what is accessible via the classloader, and we may potentially want to do some analysis of the generated .class files before they are executed to make sure they’re not calling anything nasty (ala elasticsearch-lang-kotlin plugin). Unless there is some better way to implement whitelisting at a compiler plugin level, that is. • We may also need to have people be able to extend a base class or otherwise interact with it. • It also sounds like JSR223 bindings can’t currently be made available in global scope, so users have to write “bindings[‘foo’]” which is not so elegant.
i
Ok, that’s fair enough. In this case it seems that you really will be better off with the KEEP-75 API. As of KT-28137 - I’ll do my best to make it happen as soon as possible. BTW. votes and comments often help us to better understand the priorities and pain points.
d
I 'solve' the bindings problem with JSR223 by simple text prepending. Given a script at runtime, with parameters known at compile time (or by a data structure at runtime) I create a 'prefix' string of the form val param_a = bindings['"a"] val param_b = bindings["b"]
...
then append the supplied script which can reference parameters as println( param_a ) Especially considering I have yet to get the templated scripting to work for me yet -- (havent tried in 6 months.. was painful then ) -- I don't see much advantage over this crude but effective methods. I belive that this is essentially what the script template would do -- No matter how you slice it, its "SQL Injection" -- if you allow users to pass in strings to compile whether they are 'injected' into a template or 'concatenated' at the end of a fixed set of text -- the effect is about the same