-
Notifications
You must be signed in to change notification settings - Fork 52
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
Improve ScriptService to register discovered Plugins #261
Comments
We do already parse all scripts upfront to extract the input and output parameters. Only if we find output parameter(s) which appear to represent plugin classes would we actually execute the script upfront to obtain said class(es) so that it can be registered. |
I'd love to make this happen, maybe together with the new parameter annotation from 9667fb9 Something along these lines:
|
I'd be happy to discuss in Dresden, sure. I would like to understand the use cases where you need this capability. The general goal is to allow defining Java classes in script languages and then register those classes as plugins, I understand. This is fine. However, there is a question of whether we can make it easier for the common cases. E.g., if what you want is to "write an Op in Jython", say, we might be able to make that happen without needing to explicitly define a Java class? Needs further thought and discussion. |
/cc @dietzc |
After some discussion, here a more general use case: let's consider a script #!groovy
#@autorun=true
#@name="scijava.demo"
def helloWorld() {
println "Hello World!"
}
String[] getNames() {
return ["Curtis", "Christian", "Jan"]
} If this script is parsed during startup, it should be run automatically, and the resulting functions should be usable from other scripts. (The question is whether it's required to be wrapped in a #@ScriptService scripts
/* Possible ways to import the static script methods ?? */
// import MyUtils
// import scijava.demo
scripts.import("scijava.demo")
println helloWorld()
println getNames() |
I think there are multiple different, but very related, use cases here: 1) autorun on start; 2) include as a library; and maybe (but maybe not) 3) autoinclude libraries. Autorun#@script(autorun=true)
#@name="scijava.demo"
def helloWorld() {
println "Hello World!"
}
String[] getNames() {
return ["Curtis", "Christian", "Jan"]
} Include#@script(name = "groovy-util")
def helloWorld() { println "Hello World!" }
String[] getNames() { return ["Curtis", "Christian", "Jan"] } And then in another script: #@include("groovy-util")
println helloWorld()
println getNames() Autoinclude#@script(name = "groovy-util", autoinclude = true)
def helloWorld() { println "Hello World!" }
String[] getNames() { return ["Curtis", "Christian", "Jan"] } And then in another script: println helloWorld()
println getNames() But autoincludes have similar problems to autoimports—if the base library disappears or changes, the downstream code mysteriously stops working, with very little hint why. |
Should we improve the One issue I see with your proposed syntax, @ctrueden: #@script(name = "groovy-util") What if one day, we want to have a shortcut So, should annotations like |
Yes, the conflation of syntax bothers me with this (also I think it is pretty unlikely that we will someday have a class called I also think we should make a decision about whether we put a space after the We could also conceivably use that whitespace to distinguish between "an input of type |
I like the idea of distinguishing directives (both We could be tolerant and keep accepting both To avoid confusion, we should try to document as accurate as possible of course... and not introduce breaking changes in the future. |
Great. I would phrase it more like: for reserved keywords, they take precedence over the shorthand. So to make the preprocessor recognize the word as a Java type, you can write either
OK, let's change any |
Great, so the next tasks:
Sorry for asking this, I'm still unsure about how to implement this, but would like to try it eventually. |
We are talking about implementing
Looking at
The
After thinking a bit, I think we want to paste in the included code directly. Some arguments:
Alternately, I guess the
Although before doing that, it would be good to articulate the concrete pros and cons of transclusion vs. execution. |
Yes, I'd be in favor of this, as it makes a clear distinction between directives and inputs (where the
Yes. I wonder what use cases we should support for using a common script library. Library script: #@script(name="mylib")
def myAddFive(number) {
return (number + 5)
} Usage script: #@include(name="mylib")
result = myAddFive(3) ExecutionExecution wouldn't currently work with the above use case, as the defined function isn't available in the scope of the second script. Likewise, this example currently doesn't work: #@ ScriptService scripts
script = """
def myLibraryFunction(text) {
println text
return 42
}
"""
scripts.run("foo.groovy", script, true)
result = myLibraryFunction("Hey")
println result TransclusionThe issue I see with transclusion is that in order to support all languages, we would have to copy the included code at the beginning of the script, which leads to inconsistent line numbering when exceptions are thrown. print myLibraryFunction("Hey")
def myLibraryFunction(text):
print text
return 42 Alternatively, we could aim for a bit more complex (but concise) syntax like: #@include(name="mylib")
result = mylib.myAddFive(3) In this case, we can create a |
@ctrueden wrote:
Well, they will be parsed when containing a space, but the following lines only match when Also, the current pattern does not allow spaces between the directive and the following parenthesis, which is an unneccesary restriction IMHO. When I find the time, I'll submit a PR changing the pattern and trimming the Another question: I can't see a difference in priority for An argument for execution instead of transclusion: you would be able to include scripts in a language-agnostic way, i.e. write a "library" with static utility methods in Python and re-use it like a Java class with static methods from Groovy, etc. |
After discussion with @imagejan, we have filed new issues relating to the above discussion and tangential topics:
These issues cover everything originally desired by this issue; hence, this issue is now closed in favor of the new ones. |
Additionally, issue #200 was updated to reflect the latest state of the discussion. |
If scripts in a dedicated directory contain classes annotated with
@Plugin
, they should be automatically registered by adding them to thePluginService
, so they can easily be called from other scripts.See this gitter post and subsequent posts.
(This implies that the scripts would have to be parsed first, which might complicate things.)
The text was updated successfully, but these errors were encountered: