Jon_Shier
(Jon Shier)
1
I'm attempting to implement parameter parsing for a project of mine and I can't seem to get default values for arguments working. For instance:
struct Dragonfly: ParsableCommand {
@Argument() var enableLogging: Bool
func run() throws {
DragonflyServer.run(enableLogging: enableLogging)
}
}
Dragonfly.main()
This always requires a value to always be passed. Is this not the intended use for @Argument? I see that @Option can take a default, so is that what I should use?
Additionally, it seems that @Argument() is required instead of @Argument, is that just a byproduct of the wrapper implementation? Is it something that can be fixed?
deggert
(Daniel Eggert)
2
I’m not entirely sure what you’re trying to do, but you might want to use @Flag var enableLogging: Bool instead of @Argument.
2 Likes
somu
(somu)
3
There are 2 ways you could do it @Option and @Flag
@Flag - for Bool defaults to false
@Option- you can specify the default value
Example below shows them and both of them can be omitted and will result in default values.
//When using Flag, defaults to false
//If user specifies --enableLogging, then it will be true, if user ignore it will be false
//This can be omitted
//Usage: [--enableLogging]
@Flag()
var enableLogging: Bool
//When using Option, you can specify the default value
//This can be omitted
//Usage: [--flag2 <flag2>]
@Option(default: true)
var flag2: Bool
Lantua
4
Generally, if the wrapper provides init() we can remove (). It doesn't seem to work with one with default values like what Argument provides: init(help: = default). Not sure if we should add init(), or add support to property wrapper.
You can drop the parens (i.e. just do @Foo) if the property wrapper has an init() or init(...) where all arguments have default values.
Jon_Shier
(Jon Shier)
6
@Option does what I needed. I think I was confused about @Argument vs. @Option vs. @Flag. Still seems like @Argument should support default values.
Lantua
7
It doesn't work. It is treated as not having default value. Which, for ParsableCommand, it forces me to write init() myself.
This fails to compile, Main.init() is missing.
import ArgumentParser
// Error: Type 'Main' does not conform to protocol 'ParsableArguments'
struct Main: ParsableCommand {
@Argument var i: Int
func run() throws {
print(i)
}
}
Main.main(["33"])
This works
import ArgumentParser
struct Main: ParsableCommand {
@Argument() var i: Int
func run() throws {
print(i)
}
}
Main.main(["33"])
I haven't looked at the code for this library, so I am not sure what's going on, but this works:
@propertyWrapper
struct Foo {
init(wrappedValue value: Int = 0) {
self.wrappedValue = value
}
var wrappedValue: Int
}
struct Bar {
@Foo var value: Int
}
let bar = Bar()
print(bar.value) // 0
To clarify, I was just talking in general that initialisers with all default args in property wrappers are supported now as of Swift 5.2 (I implemented them here), which allows you to do @Foo without the need to add parens.
Lantua
9
I see what's going on now, current non-beta Xcode (11.3.1) still uses Swift 5.1.3. Ah well, I can wait
. Thanks for the fix btw
.
1 Like
Since v0.0.3, it is now possible to define a default value for the @Argument.