[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Unset array doesn't work

From: Chet Ramey
Subject: Re: Unset array doesn't work
Date: Wed, 28 Feb 2018 10:27:23 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

On 2/27/18 3:49 PM, Robert Elz wrote:
>     Date:        Tue, 27 Feb 2018 11:18:40 -0500
>     From:        Chet Ramey <address@hidden>
>     Message-ID:  <address@hidden>
>   | It doesn't. Run the following script:
> OK, that looks good.  But now I am very confused.

These are two different cases -- same context vs. a previous context. Your
example is not the same as the original poster's.

>   | You'll see that the first expansion of `$var' uses the local value of IFS,
>   | the second expansion uses the default value of $' \t\n', and the global
>   | value doesn't change (or get unset) outside the function.
> Yes, and I was never expecting the global to be changed (that is, in this,
> I didn't imagine that as a possibility).
>   | The objection was that the global or previous-scope value didn't get unset
>   | when using the `unset' builtin; only in the local scope was it unset.

This was poorly phrased, but I amended it in a subsequent message.

> I was in e-mail catchup mode, I am not sure I even saw the original, but I
> do tend to read your messages, and what you said (12 Feb) was ...

The short story: dynamic scoping. We have a call tree like:

        main -> funcA -> funcB

main has a global variable var with value v1. funcA has a local variable
var with value v2. funcB runs unset var, and the value from funcA --
previous scope -- gets removed. The global var is left unchanged, and
satisfies references to $var with v1.

The original poster wanted the global value to be removed, or at least
found that running `unset' enough times that all instances in the call
chain were removed produced the behavior he wanted.

>   |  The visibility of a local variable is restricted to a function and its
>   | children,
> That's fine.
>   | and `unset' removes the currently-visible instance.
> as is that,  at least if "removes" is interpreted in one way (which the
> script you sent suggests is correct).

There is code that implements your preferred interpretation of `removed'
when the `unset' is performed in the same context as the local variable
declaration. When `unset' removes a variable at a previous scope, which
can be a calling function due to dynamic scoping, it just removes the

There are several behavior choices here. You can simply remove all
instances of the variable back to the global scope until there are no
traces of the name remaining. You can mark any local instances in previous
scopes (or the nearest previous scope that has a local instance of
that variable) with a special `unset' attribute that will cause
references to it to behave as if it were unset, leaving the global
value unchanged. Or you can remove the instance in the nearest previous
scope in the call chain, leaving other instances alone. Bash chooses
the last.

``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    address@hidden    http://tiswww.cwru.edu/~chet/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]