> +#define PM_UNSET (1<<24) /* If PM_DECLARED is also present, parameter
> + * has null value. Otherwise, parameter was
> + * unset.
> + */
> #define PM_DEFAULTED (PM_DECLARED|PM_UNSET)
It's inaccurate to say the parameter has a null value. There's no
such thing as a null value in shell. That's why the following #define
calls it PM_DEFAULTED. It means the parameter exists in a scope
(which, at least previous to this patch, also implied it has a known
type) but does not have a value (which is distinct from languages
where null/undef IS a value). This goes back to the discussion in
which PM_NULL was rejected, which as I previously said I don't want to
rehash.
The flag PM_UNSET has two meanings:
- When PM_DECLARED is absent, it indicates that the parameter was unset, typically by a call to the builtin "unset".
- The parameter is no longer considered to exist but it's not fully deleted and still hides any parameter of the same in an enclosing scope.
- Calls to "typeset -p" don't list it.
- Expansions consider that the parameter isn't set.
- Assignments revive the parameter (i.e., clear the PM_UNSET flag) but ignore all its previous attributes.
- When PM_DECLARED is present, it indicates that the parameter was declared, typically by a call to the builtin "typeset", but without any value to initialize it while the option TYPESET_TO_UNSET was enabled.
- The parameter exists but it has no value.
- Calls to "typeset -p" list it but without any value.
- Expansions consider that the parameter isn't set. In this regard, the parameter can be seen as being unset.
- Assignments initialize the parameter (and clear the PM_UNSET flag).
The distinction is important because there are cases where either only the first or only the second kind of PM_UNSET parameters are to be considered (see for example my patch
workers/54261). I think that it's important to document that these two kinds exist. I initially assumed that PM_UNSET only covered the first kind.
I agree that "has a null value" is a bad way of describing the second kind. As you point out there is no null value in Zsh and even worse the term "non-null" is already used in the Zsh documentation to designate parameters whose value isn't the empty string or the empty array.
What about the following description?
#define PM_UNSET (1<<24) /* If PM_DECLARED is present, the parameter
* was declared but with no value. Otherwise,
* the parameter was undeclared/unset and no
* longer exists. In both cases, expansions
* consider the parameter as unset.
*/
Philippe