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

Re: Hiding specials, and namerefs



-- `typeset -hn ...` is not allowed, but can be worked around, so
probably should be allowed?

Indeed. Since -h is stating how the newly created parameter should coexist with existing special ones with the same name, which sounds like something that ought to be type independent, I don't see a good reason to disallow it just for named references.

-- the ZLE parameters are already implicitly local on entry to a
widget function

I assume that's what pm->level = locallevel + 1 in function makezleparams achieves. When I first saw this line, it looked very bogus to me because it creates a parameter whose level is greater than locallevel, which is in principle forbidden. From your discussion, I infer that makezleparams is run just before calling a Zle function and has the effect of declaring all the parameters listed in zleparams as if they had been declared locally in the Zle function. When the Zle function returns, the normal end scope routine unsets and removes all the parameters, which has the advantage that they never become visible to the interactive command line.


Now, speaking of special parameters, could anyone explain to me what is supposed to happen if one declares without -h a local parameter with the same name as a special parameter?

The documentation suggests that without -h the local parameter keeps the special effects of the enclosing special parameter. Apparently a new parameter with its own state is created:

% () { echo $SECONDS; local SECONDS=10; echo $SECONDS; sleep 1; echo $SECONDS }; echo $SECONDS
703041
10
11
703042

How is that possible? How can the new parameter have its own state but still have the special effects? Is it because the local parameter reuses the same gsu but gets its own u? Or, is the special paramater's u being saved, reused and restored when the local parameter goes away?

For many special parameters, the state is stored in a dedicated C variable. For example the Zsh HOME parameter is backed by this C home variable. I assume that a number of features that rely on the Zsh HOME parameter directly access the C home variable. For instance, I assume that the cd command accesses the C variable when it needs to know what the HOME directory is. How is it possible to have multiple instances of the same special parameter that each have their own state when there is a single C variable to back them?

Local HOME parameters, like local SECONDS parameters, have their own state but still keep the special effect of the global special parameter:

% zsh -c 'HOME=/etc; cd && pwd; () { local HOME=/tmp; cd && pwd }; cd && pwd'
/etc
/tmp
/etc

This shows that there are two states but apparently both are somehow connected to the C home variable. Thanks to references, it's possible to access both parameters from within the same scope. What is supposed to happen if we try that?

% zsh -c 'HOME=/etc; cd && pwd; () { local -n GHOME=HOME; local HOME=/tmp; cd && pwd; GHOME=/usr; cd && pwd; echo $HOME }; cd && pwd'
/etc
/tmp
zsh: segmentation fault

That code should certainly not segfault but it's not clear to me what it should do. What directory should cd consider to be the home directory after GHOME=/usr? And what should the value of the local HOME parameter be after that assignment?

I haven't yet looked at the implementation. That's my next step to understand what's going on but if anyone has an explanation of what is the expected behaviour, it would be very welcome.

Philippe




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