[Top][All Lists]

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

Re: functions can fully unset local vars in other scopes

From: Koichi Murase
Subject: Re: functions can fully unset local vars in other scopes
Date: Fri, 29 Jul 2022 11:42:07 +0900

2022年7月29日(金) 10:59 Emanuele Torre <torreemanuele6@gmail.com>:
> Description:
>   `bash' does not let `unset' fully undeclare local variables. (so that
>   they can be used later as `local' variables without needing to
>   redeclare them I assume.)
>       [...]
>   However, other functions are allowed to delete those variables:

This is a documented behavior:

>From Bash Reference Manul - 3.3 Shell Functions
> The unset builtin also acts using the same dynamic scope: if a
> variable is local to the current scope, unset will unset it;
> otherwise the unset will refer to the variable found in any calling
> scope as described above. If a variable at the current local scope
> is unset, it will remain so until it is reset in that scope or until
> the function returns. Once the function returns, any instance of the
> variable at a previous scope will become visible. If the unset acts
> on a variable at a previous scope, any instance of a variable with
> that name that had been shadowed will become visible.

There has been a long discussion before.


Also, I would like to repeat myself in that thread.  The dynamic
unsetting has existing applications [see the following my reply]:



> This enables defininng a "really_unset" function like so:
>     really_unset () { unset "$@" ;}
> Which may be useful I guess.

This is a well-known idiom and is already used in some places as


This is also used for Freddy Vulto's upvars trick as Greg has cited.


> But I think allowing functions to unset local variables from other
> functions defeats the whole purpose of having that `unset'
> behaviour. This enables `local' variable to unexpectedly become
> global after a function is called.

I think these two cases will never be mixed.  Because when a user does
not intend to remove the variable placeholder of the previous scopes,
the user unsets a variable that is declared within the same function.
When a user intends to remove that of the previous scopes, the
`local-variable name' can become global, but it is just what the user


> Fix:
>   I think calling `unset -v x' (where `x' is a local variable not in the
>   current scope) should behave as if it was called in the scope of `x',
>   so `x' should remain declared in that scope with no attributes and no
>   value.

This is what `shopt -s localvar_unset' does.

> It may be nice to also add a "force" option for `unset' that makes it
> actually unset the variable if it is `local'. Since this could be
> useful in some cases and it won't be possible after the behaviour is
> changed.

For this purpose, you can always use `unlocal' referenced above.


reply via email to

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