Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: More rabbit-holes with unset variables

On Fri, Nov 27, 2020 at 2:01 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> My use of "rabbit holes" has been even more prophetic than I expected.
> (Ironically, spellcheck wants to correct that to "pathetic".)

There's no rabbit hole here. It's obvious that zsh's behavior is inconsistent.

If trying to defend that it's not seems like an impossible endless
endeavor, well, maybe there's a reason for that.

> On Thu, Nov 26, 2020 at 5:51 PM Felipe Contreras
> <felipe.contreras@xxxxxxxxx> wrote:
> >
> > On Thu, Nov 26, 2020 at 6:23 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> > >
> > > The point is that the exported value DOES NOT exist in this example;
> > > if you were to look at the C global "environ" array following "export
> > > FOO", it would not have (a pointer to a string containing) "FOO" in
> > > it.
> >
> > How do you know?
> By paying attention to context?
> We're not talking about Oliver's example at this point, we're talking
> specifically about the case where "export FOOBAR" creates a global
> variable that did not exist before.  If it did previously exist, then
> the internal and environment namespaces would be the same.  The only
> way for them to differ is when FOOBAR did not already exist.

You should not be so assuming as to what "we" are talking about, maybe
you were not talking about that, I was, and it should be clear from
where we came from:

> > > > > > It appears that export VAR will not export an empty VAR even in zsh
(unless you do VAR=""). So zsh's not exactly consistent.  typeset [-x] is
arguably just a variant of export.

> > > > > > This does change how I regard zsh's behaviour. It isn't zsh taking a
different but equally valid approach on an extension but an sh incompatibility.
It once was a bug even if now too entrenched.

> > > > > It doesn't export the empty string at the time the parameter is
declared, but it does consistently set it to empty string internally:

> > > > And you don't find it inconsistent that the internal value is
*different* from the exported value?

> > > That's a loaded question, because to answer it requires conceding that
there exists an exported value from which the internal value differs.  There's
no way to "see" the export namespace without forking an external process, so
only the internal value matters.

> > No. The exported value exists whether you decide to look at it or not.

> The point is that the exported value DOES NOT exist in this example

Cleary I am talking about Oliver's example: echo ${FOO-replacement}.

> > You used precisely this argument when I brought up this example:
> Not the same, because the behavior of export vs. local (typeset in
> function context) is not the same; the latter always creates a new
> variable, and that variable doesn't inherit from scope.

Analogies don't have to be the same.

> > The inconsistency between the internal and external value *only*
> > happens in zsh, and it most definitely exists.
> I have never denied that.  What I said was that if you never leave
> zsh, you can't tell.  That you can tell by forking off /bin/sh is
> because of the way the internal and external namespaces are managed,
> not because of the way the internal namespace works, and I'm
> unsuccessfully attempting to keep this thread focused on the latter.

It doesn't matter if you can tell or not; the two values exist, and
they are different, and they are different *only* in zsh.

> > To be consistent, either these two are the same:
> >
> >   typeset -x FOO
> >   typeset -x FOO=""
> >
> > Or these two are different:
> >
> >   typeset FOO
> >   typeset FOO=""
> In the internal namespace, and starting from a name FOO that's never
> been used/does not appear in the process environment, in zsh all of
> these do the same thing:
> declare FOO
> local FOO
> export FOO
> To use Daniel's "${verb}s a variable" from the other thread, ${verb}
> is 'creates an internal parameter to represent'.  The entirety of
> these two discussion threads is supposed to be about when it is
> appropriate for that to have a default value, and what it means for it
> not to; currently it always has one.
> Specifically for "export" there are two additional requirements:
> 1) If the variable already exists with a value, then variable=value is
> added to the environment.
> 2) If a value is later assigned to the variable, then variable=value
> is added to the environment.
> Neither of those requirements is met under the stated conditions, so
> nothing is added to the environment.

You are just describing existing behavior.

> This is entirely separate from whether there is a default.

No, it isn't. This is an unsubstantiated claim.

*If* you are going to assign a default value, then this is the value
that should be exported. Otherwise the values will be different, and
there would be an inconsistency.

*Or* just don't assign any default value, and this way both the local
and exported values are also the same.

So clearly the inconsistency has to do with the default.

> Again starting from a previously nonexistent FOO, all of these are
> also the same:
> declare FOO=anything
> local FOO=anything
> export FOO=anything
> These explicitly do two things:  First ${verb}, and then assign.  So
> for export, the second additional requirement is met, and
> variable=value is added to the environment.

Again, explaining current behavior.

> Is there an inconsistency from the viewpoint of an omniscient
> observer?  Yes.

Good. That's all I'm saying, and that's what Oliver said (zsh's not
exactly consistent).


Felipe Contreras

Messages sorted by: Reverse Date, Date, Thread, Author