-
Notifications
You must be signed in to change notification settings - Fork 428
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
Document static vs non-static nested classes (was: Kotlin: failure when declaring IParameterPreprocessor as inner class) #1297
Comments
I believe this is similar to inner classes vs static inner classes in Java, except that in Kotlin, nested classes are static by default, whereas in Java they require the In Kotlin, nested classes that are marked as So, where in Java, static inner classes work out of the box, in Kotlin, nested classes without Inner classes can still be made to work in picocli, but require a factory that provides the reference to the outer class. (This is a test Factory. In reality, the problem is that this factory requires an instance of the outer class, which may not be constructed yet. This could be fixed by making the factory return the specified instance of the outer class, so the outer class effectively becomes a singleton. But I suspect this configuration will only be useful to applications in some rare cases...) |
Thanks for sheding more light on this!
I agree. I tend to think that there are more important issues in the backlog/ issue list. It's up to you to decide whether we want to pursue this ticket or not. If we won't get a solution in the long run, this should be documented somewhere IMHO (chapter |
Not sure: I don't think this is a Kotlin problem, this is more general. For example, in Java: class Outer {
@Option(names = "--option", preprocessor = Outer.InnerPreprocessor.class)
String value;
// non-static
class InnerPreprocessor implements IParameterPreprocessor {
public boolean preprocess(Stack<String> args, CommandSpec cmd, ArgSpec arg, Map<String, Object> info) {
return false;
}
}
public static void main(String... args) {
new CommandLine(new Outer()).parseArgs(args); // this will fail with "Cannot instantiate InnerPreprocessor"
// To instantiate the above `InnerPreprocessor` in a Java program, we need to use this strange syntax:
// Outer o = new Outer();
// InnerPreprocessor inner = o.new InnerPreprocessor();
//
// Reflective access needs to use the synthetic constructor that
// takes an instance of the enclosing class as a parameter.
}
} This would give the same "Cannot instantiate" problem as the Kotlin example above. It would be very rare for an application to use a non-static inner class for picocli's "plugin" components like For cases where it truly is necessary to share information between a nested class and its enclosing instance:
I have not heard anyone requesting this feature, so it probably is not a common requirement. |
Looking at recent comments on #803, it may be a good idea to add a few words about static vs non-static nested classes in the user manual. |
@pedrolamarao, @deining I added some CAUTION admonitions to the Custom Parameter Processing and Multi Parameter Type Converters sections. Feel free to suggest more if you can think of any. |
With PR #1307, I added two more CAUTION admonitions. Two more thoughts on this:
Just my two cents ... |
Yes, I like that idea. Between "Tips & Tricks" and "Dependency Injection" is probably a good insertion point. Some limitations are already documented, like Variable Arity Limitations, Argument Group Limitations, Limitations of Variable Interpolation, default values for annotated fields, interactive positional parameters, Optional Parameter Limitations. For some of these it may make sense to repeat the content or expand on the content with an example, for other limitations that already have extensive documentation, perhaps we can just link from the new chapter to the existing section.
Can we come up with a good example of something where a
Merged. Thank you! 🙏 |
I separated out #1317 for an additional "Known Limitations" chapter. After some more pondering I don't think that creating custom factories for non-static nested classes is something that should be encouraged, so I prefer to not mention this idea in the Custom Factories section.
@deining Are you okay to close this ticket? |
…rter and IModelTransformer (remkop#1297)
…n-static inner classes" This reverts commit d99bfab.
…ypeConverter and IModelTransformer (remkop#1297)" This reverts commit 1390006.
…n-static inner classes" This reverts commit d99bfab.
…ypeConverter and IModelTransformer (remkop#1297)" This reverts commit 1390006.
Minimum working example which runs flawlessly:
As soon as I enable the preprocessor for option
-a
by uncommenting line 10, I'm getting an error:The error is due to the fact that
MyPreprocessor
is declared as inner class. As soon as remove theinner
keyword, everything is fine again. However, since there might be good reasons to make use of an inner class, I'm asking myself if there is a way to make that work. I didn't dig into this further, but I found this resource that might be helpful.Any help is appreciated!
The text was updated successfully, but these errors were encountered: