[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: using a variable from global scope or checking whether it is local t
From: |
Koichi Murase |
Subject: |
Re: using a variable from global scope or checking whether it is local to some scope |
Date: |
Fri, 20 Oct 2023 09:40:17 +0900 |
I have implementations in my framework.
2023年10月20日(金) 0:13 Christoph Anton Mitterer <calestyo@scientia.org>:
> Are there ways to achieve either of the following in a function:
>
> 1) I want to make sure that a variable is used from the global scope
> even if my function was possibly (which I don't know) called from
> another function (which may have made the variable local itself.
To set a global variable, you can use "declare -g gvar=value".
Unfortunately, we cannot use `declare -g gvar' to get the value in the
global environment, though I think it is valid to request such a
feature.
To read a global variable, you can repeat `unset -v' until you reach
the global variable in a command substitution and return the result
through stdout. Since it is performed in a subshell, it is not
destructive in the main-shell environment (If you don't like fork, I
don't know the other non-destructive way). There is a case that this
approach doesn't work: If any local variable of the same name in the
function call stack has a readonly attribute, it cannot unset the
local variable, so it is impossible to access the global variable
anyway. If we assume that all the local variables of the same name are
not readonly, one can detect the global variable by setting `declare
-g -r var' in advance. When `unset -v' fails, it is expected to be the
global variable.
This is implemented in the following function:
https://github.com/akinomyoga/ble.sh/blob/742cf2cce6792a9460d38e92f715beb9870a6ff3/src/util.sh#L3031-L3151
You can use `ble/util/print-global-definitions varname' from inside a
function to get the declaration of the variable. If you want to copy
it to the current scope, you may simply run eval
"$(ble/util/print-global-definitions varname)".
> 2) Or at least find out, whether in a function, the variable is
> actually from the global scope or not.
In a subshell, you can set the readonly attribute to the currently
visible variable and try to override it in a child function call. It
fails if the variable is a global variable because a global readonly
variable is not allowed to be hidden even by a local variable. It
succeeds if the variable is local because a local readonly variable is
allowed to be hidden by another local variable declared in a child
function call. The implementation is simple:
https://github.com/akinomyoga/ble.sh/blob/742cf2cce6792a9460d38e92f715beb9870a6ff3/src/util.sh#L469-L472
Koichi