GO cobra: space separated values in StringArray flags - go

In GO's Cobra, lib for making CLIs, there are two input flags accepting multiple values being passed. One of the options is StringArray, when used as follows:
--flag=value1 --flag=value2
it yields an array ["value1", "value2"].
I am working on a drop-in replacement for a tool that expects somewhat more complex input:
--flag=valueA1 valueB1 --flag=valueA2 valueB2
the array it should yield would be ["valueA1 valueB1", "valueA2 valueB2"]
is there a way in cobra to parse the entire string until the next flag and include it in StringArray value like above?

There isn't a built-in way in cobra to do this, as there will be ambiguity. For example, in the case when there is also a sub-command named valueB1 or valueB2, it's not clear whether those should be executed as subcommands or interpreted as additional argument to --flag.
The standard way to support an input like this is to expect the the input values are quoted, and cobra supports that. E.g.:
--flag="valueA1 valueB1" --flag="valueA2 valueB2"

Related

Anonymous struct as pipeline in template

Is there a way to do the following in a html/template?
{{template "mytemplate" struct{Foo1, Foo2 string}{"Bar1", "Bar2"}}}
Actually in the template, like above. Not via a function registered in FuncMap which returns the struct.
I tried it, but Parse panics, see Playground. Maybe just the syntax is wrong?
As noted by others, it's not possible. Templates are parsed at runtime, without the help of the Go compiler. So allowing arbitrary Go syntax would not be feasible (although note that it wouldn't be impossible, as the standard lib contains all the tools to parse Go source text, see packages "prefixed" with go/ in the standard lib). By design philosophy, complex logic should be outside of templates.
Back to your example:
struct{Foo1, Foo2 string}{"Bar1", "Bar2"}
This is a struct composite literal and it is not supported in templates, neither when invoking another template nor at other places.
Invoking another template with a custom "argument" has the following syntax (quoting from text/template: Actions):
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
TL;DR; A pipeline may be a constant, an expression denoting a field or method of some value (where the method will be called and its return value will be used), it may be a call to some "template-builtin" function or a custom registered function, or a value in a map.
Where Pipeline is:
A pipeline is a possibly chained sequence of "commands". A command is a simple value (argument) or a function or method call, possibly with multiple arguments:
Argument
The result is the value of evaluating the argument.
.Method [Argument...]
The method can be alone or the last element of a chain but,
unlike methods in the middle of a chain, it can take arguments.
The result is the value of calling the method with the
arguments:
dot.Method(Argument1, etc.)
functionName [Argument...]
The result is the value of calling the function associated
with the name:
function(Argument1, etc.)
Functions and function names are described below.
And an Argument is:
An argument is a simple value, denoted by one of the following.
- A boolean, string, character, integer, floating-point, imaginary
or complex constant in Go syntax. These behave like Go's untyped
constants. Note that, as in Go, whether a large integer constant
overflows when assigned or passed to a function can depend on whether
the host machine's ints are 32 or 64 bits.
- The keyword nil, representing an untyped Go nil.
- The character '.' (period):
.
The result is the value of dot.
- A variable name, which is a (possibly empty) alphanumeric string
preceded by a dollar sign, such as
$piOver2
or
$
The result is the value of the variable.
Variables are described below.
- The name of a field of the data, which must be a struct, preceded
by a period, such as
.Field
The result is the value of the field. Field invocations may be
chained:
.Field1.Field2
Fields can also be evaluated on variables, including chaining:
$x.Field1.Field2
- The name of a key of the data, which must be a map, preceded
by a period, such as
.Key
The result is the map element value indexed by the key.
Key invocations may be chained and combined with fields to any
depth:
.Field1.Key1.Field2.Key2
Although the key must be an alphanumeric identifier, unlike with
field names they do not need to start with an upper case letter.
Keys can also be evaluated on variables, including chaining:
$x.key1.key2
- The name of a niladic method of the data, preceded by a period,
such as
.Method
The result is the value of invoking the method with dot as the
receiver, dot.Method(). Such a method must have one return value (of
any type) or two return values, the second of which is an error.
If it has two and the returned error is non-nil, execution terminates
and an error is returned to the caller as the value of Execute.
Method invocations may be chained and combined with fields and keys
to any depth:
.Field1.Key1.Method1.Field2.Key2.Method2
Methods can also be evaluated on variables, including chaining:
$x.Method1.Field
- The name of a niladic function, such as
fun
The result is the value of invoking the function, fun(). The return
types and values behave as in methods. Functions and function
names are described below.
- A parenthesized instance of one the above, for grouping. The result
may be accessed by a field or map key invocation.
print (.F1 arg1) (.F2 arg2)
(.StructValuedMethod "arg").Field
The proper solution would be to register a custom function that constructs the value you want to pass to the template invocation, as you can see in this related / possible duplicate: Golang pass multiple values from template to template?
Another, half solution could be to use the builtin print or printf functions to concatenate the values you want to pass, but that would require to split in the other template.
As mentioned by #icza, this is not possible.
However, you might want to provide a generic dict function to templates to allow to build a map[string]interface{} from a list of arguments. This is explained in this other answer: https://stackoverflow.com/a/18276968/328115

What is the syntax for describing how to call a command?

If I have this command:
do_something
And requires 2 arguments argument_1 argument_2
argument_1 can be anything
argument_2 only can be true or false
A non-required third argument can be added argument_3
What is the standard to describe a script calling template?
I remember to have read somewhere about the different meanings of <> and [] and {}. For example:
<> mean required
[] mean non-required
{} contains a list of possible values
So for my example it will be
do_someting <argument_1> {true,false} [argument_3]
But I don't find any place that is confirming this syntax.
I would write the following:
do_someting argument_1 {true|false} [argument_3]
I think mendatory arguments don't need any kind of braces, it looks clearer like that. Furthermore, the pipe feels more standard to represent an "or" statement.
I am not aware of such standard, but you can have a look at Google recommendations or docopt for example. Also, here is a POSIX document which may interest you.

Ruby: What's the difference between IO and ARGV?

I've been trying to understand the differences between the two, but as of now I have a very rudimentary understanding. ARGV is a subset of IO I believe. I know that ARGV returns an array when called into a Ruby script, but IO does the same thing as well. Can anyone explain this topic to me or direct me to a good explanation? I've searched multiple blogs but to no avail.
Thanks!
ARGV is an array:
> ARGV.class
=> Array
This array contains the command line arguments for your script. For example:
$ cat pancakes.rb
puts ARGV.inspect
$ ruby pancakes.rb -where is house
["-where", "is", "house"]
IO is quite a bit different. IO is:
[...] the basis for all input and output in Ruby. [...]
Many of the examples in this section use the File class, the only standard subclass of IO. The two classes are closely associated. Like the File class, the Socket library subclasses from IO (such as TCPSocket or UDPSocket).
IO is the base class for file-like things in Ruby.
Perhaps you're thinking of ARGF rather than ARGV:
ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.
The arguments passed to your script are stored in the ARGV Array, one argument per element. ARGF assumes that any arguments that aren't filenames have been removed from ARGV.
[...]
If ARGV is empty, ARGF acts as if it contained STDIN, i.e. the data piped to your script.
So you can use ARGF like an IO that lets you say:
$ your_script some_file
and
$ some_command | your_script
without your_script really having to care about which way it is called.
The IO class is the basis for all input and output in Ruby. An I/O stream may be duplexed (that is, bidirectional), and so may use more than one native operating system stream.
Many of the examples in this section use the File class, the only
standard subclass of IO. The two classes are closely associated. Like
the File class, the Socket library subclasses from IO (such as
TCPSocket or UDPSocket).
The Kernel#open method can create an IO (or File) object for these
types of arguments:
A plain string represents a filename suitable for the underlying
operating system. A string starting with "|" indicates a subprocess.
The remainder of the string following the "|" is invoked as a process
with appropriate input/output channels connected to it. A string equal
to "|-" will create another Ruby instance as a subprocess. The IO may
be opened with different file modes (read-only, write-only) and
encodings for proper conversion. See ::new for these options. See
Kernel#open for details of the various command formats described
above.
Source: http://www.ruby-doc.org/core-2.1.2/IO.html
ARGF is a stream designed for use in scripts that process files given as command-line arguments or
passed in via STDIN.
The arguments passed to your script are stored in the ARGV Array, one
argument per element. ARGF assumes that any arguments that aren't
filenames have been removed from ARGV.
argv → ARGV Returns the ARGV array, which contains the arguments
passed to your script, one per element.
Source: http://www.ruby-doc.org/core-2.1.2/ARGF.html

Why are bash variables 'different'?

Is there some reason why bash 'variables' are different from variables in other 'normal' programming languages?
Is it due to the fact that they are set by the output of previous programs or have to be set by some kind of literal text, ie they have to be set by the output of some program or something outputting text through standard input/output or the console or such like?
I am at a loss to use the right vocabulary, but can anyone who can understands what I trying to say and perhaps use the right words or point me some docs where I can understand bash variable concepts better.
In most languages, variables can contain different kinds of values. For example, in Python a variable can be a number that you can do arithmetics on (a-1), an array or string you can split (a[3:]), or a custom, nested object (person.name.first_name).
In bash, you can't do any of this directly. If I understood you right, you asked why this is.
There are two reasons why you can't really do the same in bash.
One: environment variables are (conventionally) simple key=value strings, and the original sh was a pretty thin wrapper on top of the Unix process model. Bash works the same, for technical and compatibility reasons. Since all variables are (based on) strings, you can't really have rich, nested types.
This also means that you can't set a variable in a subshell/subscript you call. The variable won't be set in the parent script, because that's not how environment variables work.
Two: Original sh didn't separate code and data, since this makes it easier to work with interactively. Sh treated all non-special characters as literal. I.e. find / -name foo was considered four literal strings: a command and three arguments.
Bash can't just decide that find / -name now means "the value of the variable find divided by the negated value of variable name", since that would mean everyone's find commands would start breaking. This is why you can't have the simple dereferencing syntax other languages do.
Even $name-1 can't be used to substract, because it could just as easily be intended as part of $name-1-12-2012.tar.gz, a filename with a timestamp.
I would say it has to do with Bash functions. Bash functions cannot return a value, only a status code.
So with Bash you can have a function
foo ()
{
grep bar baz
}
But if you try to "save" the return value of the function
quux=$?
It is merely saving the exit status, not any value. Contrast this with a language such as Javascript, functions can actually return values.
foo ()
{
return document.getElementById("dog").getAttribute("cat");
}
and save like this
quux = foo();

Any reason NOT to always use keyword arguments?

Before jumping into python, I had started with some Objective-C / Cocoa books. As I recall, most functions required keyword arguments to be explicitly stated. Until recently I forgot all about this, and just used positional arguments in Python. But lately, I've ran into a few bugs which resulted from improper positions - sneaky little things they were.
Got me thinking - generally speaking, unless there is a circumstance that specifically requires non-keyword arguments - is there any good reason NOT to use keyword arguments? Is it considered bad style to always use them, even for simple functions?
I feel like as most of my 50-line programs have been scaling to 500 or more lines regularly, if I just get accustomed to always using keyword arguments, the code will be more easily readable and maintainable as it grows. Any reason this might not be so?
UPDATE:
The general impression I am getting is that its a style preference, with many good arguments that they should generally not be used for very simple arguments, but are otherwise consistent with good style. Before accepting I just want to clarify though - is there any specific non-style problems that arise from this method - for instance, significant performance hits?
There isn't any reason not to use keyword arguments apart from the clarity and readability of the code. The choice of whether to use keywords should be based on whether the keyword adds additional useful information when reading the code or not.
I follow the following general rule:
If it is hard to infer the function (name) of the argument from the function name – pass it by keyword (e.g. I wouldn't want to have text.splitlines(True) in my code).
If it is hard to infer the order of the arguments, for example if you have too many arguments, or when you have independent optional arguments – pass it by keyword (e.g. funkyplot(x, y, None, None, None, None, None, None, 'red') doesn't look particularly nice).
Never pass the first few arguments by keyword if the purpose of the argument is obvious. You see, sin(2*pi) is better than sin(value=2*pi), the same is true for plot(x, y, z).
In most cases, stable mandatory arguments would be positional, and optional arguments would be keyword.
There's also a possible difference in performance, because in every implementation the keyword arguments would be slightly slower, but considering this would be generally a premature optimisation and the results from it wouldn't be significant, I don't think it's crucial for the decision.
UPDATE: Non-stylistical concerns
Keyword arguments can do everything that positional arguments can, and if you're defining a new API there are no technical disadvantages apart from possible performance issues. However, you might have little issues if you're combining your code with existing elements.
Consider the following:
If you make your function take keyword arguments, that becomes part of your interface.
You can't replace your function with another that has a similar signature but a different keyword for the same argument.
You might want to use a decorator or another utility on your function that assumes that your function takes a positional argument. Unbound methods are an example of such utility because they always pass the first argument as positional after reading it as positional, so cls.method(self=cls_instance) doesn't work even if there is an argument self in the definition.
None of these would be a real issue if you design your API well and document the use of keyword arguments, especially if you're not designing something that should be interchangeable with something that already exists.
If your consideration is to improve readability of function calls, why not simply declare functions as normal, e.g.
def test(x, y):
print "x:", x
print "y:", y
And simply call functions by declaring the names explicitly, like so:
test(y=4, x=1)
Which obviously gives you the output:
x: 1
y: 4
or this exercise would be pointless.
This avoids having arguments be optional and needing default values (unless you want them to be, in which case just go ahead with the keyword arguments! :) and gives you all the versatility and improved readability of named arguments that are not limited by order.
Well, there are a few reasons why I would not do that.
If all your arguments are keyword arguments, it increases noise in the code and it might remove clarity about which arguments are required and which ones are optionnal.
Also, if I have to use your code, I might want to kill you !! (Just kidding), but having to type the name of all the parameters everytime... not so fun.
Just to offer a different argument, I think there are some cases in which named parameters might improve readability. For example, imagine a function that creates a user in your system:
create_user("George", "Martin", "g.m#example.com", "payments#example.com", "1", "Radius Circle")
From that definition, it is not at all clear what these values might mean, even though they are all required, however with named parameters it is always obvious:
create_user(
first_name="George",
last_name="Martin",
contact_email="g.m#example.com",
billing_email="payments#example.com",
street_number="1",
street_name="Radius Circle")
I remember reading a very good explanation of "options" in UNIX programs: "Options are meant to be optional, a program should be able to run without any options at all".
The same principle could be applied to keyword arguments in Python.
These kind of arguments should allow a user to "customize" the function call, but a function should be able to be called without any implicit keyword-value argument pairs at all.
Sometimes, things should be simple because they are simple.
If you always enforce you to use keyword arguments on every function call, soon your code will be unreadable.
When Python's built-in compile() and __import__() functions gain keyword argument support, the same argument was made in favor of clarity. There appears to be no significant performance hit, if any.
Now, if you make your functions only accept keyword arguments (as opposed to passing the positional parameters using keywords when calling them, which is allowed), then yes, it'd be annoying.
I don't see the purpose of using keyword arguments when the meaning of the arguments is obvious
Keyword args are good when you have long parameter lists with no well defined order (that you can't easily come up with a clear scheme to remember); however there are many situations where using them is overkill or makes the program less clear.
First, sometimes is much easier to remember the order of keywords than the names of keyword arguments, and specifying the names of arguments could make it less clear. Take randint from scipy.random with the following docstring:
randint(low, high=None, size=None)
Return random integers x such that low <= x < high.
If high is None, then 0 <= x < low.
When wanting to generate a random int from [0,10) its clearer to write randint(10) than randint(low=10) in my view. If you need to generate an array with 100 numbers in [0,10) you can probably remember the argument order and write randint(0, 10, 100). However, you may not remember the variable names (e.g., is the first parameter low, lower, start, min, minimum) and once you have to look up the parameter names, you might as well not use them (as you just looked up the proper order).
Also consider variadic functions (ones with variable number of parameters that are anonymous themselves). E.g., you may want to write something like:
def square_sum(*params):
sq_sum = 0
for p in params:
sq_sum += p*p
return sq_sum
that can be applied a bunch of bare parameters (square_sum(1,2,3,4,5) # gives 55 ). Sure you could have written the function to take an named keyword iterable def square_sum(params): and called it like square_sum([1,2,3,4,5]) but that may be less intuitive, especially when there's no potential confusion about the argument name or its contents.
A mistake I often do is that I forget that positional arguments have to be specified before any keyword arguments, when calling a function. If testing is a function, then:
testing(arg = 20, 56)
gives a SyntaxError message; something like:
SyntaxError: non-keyword arg after keyword arg
It is easy to fix of course, it's just annoying. So in the case of few - lines programs as the ones you mention, I would probably just go with positional arguments after giving nice, descriptive names to the parameters of the function. I don't know if what I mention is that big of a problem though.
One downside I could see is that you'd have to think of a sensible default value for everything, and in many cases there might not be any sensible default value (including None). Then you would feel obliged to write a whole lot of error handling code for the cases where a kwarg that logically should be a positional arg was left unspecified.
Imagine writing stuff like this every time..
def logarithm(x=None):
if x is None:
raise TypeError("You can't do log(None), sorry!")

Resources