This relates to the way variables are expanded. If a variable contains more than one element (is a list), and an argument contains a variable, then the argument is expanded separately for each element in the list.
For example:
> set vals 1 2 3
> echo item_$vals
item_1 item_2 item_3
So in the sample code:
test1 ci -m "test1 str2"
This invokes the test1 function with $argv set to a list of three elements: ci
, -m
, and test2 str2
.
echo argv: $argv
Spaces separate arguments, so the text argv: $argv
contains two separate (unexpanded) arguments. They get expanded separately.
Now for the second case:
echo argv:$argv
The text argv:$argv
contains no spaces, so it is just one (unexpanded) argument. Therefore fish separately expands the text for every element in the list, yielding three arguments:
argv:$argv
→ argv:{ci, -m, test2 str}
→ argv:ci argv:-m argv:test2 str
Those arguments are then passed to echo.
If you don't want this expansion behavior, you can use double quotes, which always results in a single argument. In double quotes, list variables are joined using a space:
> set vals 1 2 3
> echo "item_$vals"
item_1 2 3
The quoted string expanded to a single argument (that contained spaces).
For completeness, single quotes defeat variable expansion entirely:
> set vals 1 2 3
> echo 'item_$vals'
item_$vals
The unquoted list expansion behavior is useful for constructing patterns. To generate a list of file1.txt through file5.txt:
> echo file(seq 5).txt
file1.txt file2.txt file3.txt file4.txt file5.txt
Hope that clears things up.