Search code examples
scopeevalzshlocal-variables

local variable changes value late


If I have a function my-func like this:

my-func(){
    v=$1
    eval $2
}

Then this is the Output I get for running my-func 123 "echo $v":

Running it for the first time:

#nothing

Running it for the second+ time:

123

If I now run my-func 789 "echo $v", then I get the following output for the first time:

123

And this for the second+ time:

789

So, why is the Output delayed by one and how can I fix it?


Solution

  • I don't know what makes arundeep chohan believe that the line at the end of your function is somehow being run before the lines before. That is not what is happening.

    There are two things to remember here:

    • Arguments undergo variable expansion on the command-line before being sent through to the function; and

    • Variables defined inside a functions are, by default, global in scope, so they will be available to the entire shell upon creation, which happens during the first call to the function when execution reaches the line in which the variable is declared. Unless a variable is also exported, it ceases to exist when the shell process is destroyed, or if it gets unset.

    Here's your function definition:

    my-func(){
        v=$1
        eval $2
    }
    

    Here's the sequence of commands you entered as described in your question; comments to provide insight to what is happening at the command line before the function receives the arguments; and the output of each printed immediately below:

    $ my-func 123 "echo $v" # my-func 123 "echo "
    $ my-func 123 "echo $v" # my-func 123 "echo 123"
    123
    $ my-func 789 "echo $v" # my-func 123 "echo 123"
    123
    $ my-func 789 "echo $v" # my-func 123 "echo 789
    789