Question

Please consider the following code

function test1
echo count:(count $argv) argv: $argv
end

function test2
echo count:(count $argv) argv:$argv
end

test1 ci -m "test1 str2"
test2 ci -m "test2 str2"

why am I getting this output?!

~  source test.fish                                   Sat Nov  2 12:18:26 EDT 2013
count:3 argv: ci -m test1 str2
count:3 argv:ci argv:-m argv:test2 str2

note the argv: repetition on the second call.

thank you

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top