Damien Flament
Damien Flament

Reputation: 1563

Using local parameter with the same name of a special one within a function

As I like to use descriptive parameter names, I often tried to use variable names already used by Zsh itself.

As it took me into trouble in the past, I now wrap my script in a main function named after the script. Then I declare all my local parameter using the local keyword.

But some parameters seems to not allow hiding them in the local scope:

function foo
{
    local commands=(bar baz)
    local status=0

    echo ${(F)commands}
    echo $status
}

Here, the local commands parameter is used in place of the special one.

But as the status parameter is read-only, I got the following error:

zdm:6: read-only variable: status

I think that the local keyword allow to use a special parameter in a local scope but it does not change the way it was declared.

Upvotes: 0

Views: 185

Answers (1)

Damien Flament
Damien Flament

Reputation: 1563

To use a special parameter name within a local scope, you have to hide it explicitly using the -h flag of the typeset builtin:

typeset -h status

As you want to declare it as local, use the local keyword which also supports that flag:

local -h status

You can also use the private keyword from the zsh/param/private module:

zmodload zsh/param/private

private -h status

The -h flag

From the Zsh manual:

-h

Hide: only useful for special parameters (those marked <S> in the table in Parameters Set By The Shell), and for local parameters with the same name as a special parameter, though harmless for others.

A special parameter with this attribute will not retain its special effect when made local. Thus after typeset -h PATH, a function containing typeset PATH will create an ordinary local parameter without the usual behaviour of PATH.

Alternatively, the local parameter may itself be given this attribute; hence inside a function typeset -h PATH creates an ordinary local parameter and the special PATH parameter is not altered in any way.

It is also possible to create a local parameter using typeset +h special, where the local copy of special will retain its special properties regardless of having the -h attribute.

Global special parameters loaded from shell modules (currently those in zsh/mapfile and zsh/parameter) are automatically given the -h attribute to avoid name clashes.

Local parameters

For a more understandable explanation, see the Zsh manual page about the local parameters.

Upvotes: 1

Related Questions