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

Re: Issue with VAR=foo cmd where VAR is a named reference



Philippe Altherr wrote:
> Could we reconcile both approaches? Actually, yes. The current implementation
> forbids the flagging of references for export. This could be changed. It would
> raise the question of what should be exported for a reference "ref". I see only
> two possibilities that make sense: either "$ref" or "${(!)ref}". The former is
> technically difficult to implement efficiently while the latter is trivial.
> It's also what Bash does:
>
> % bash -c 'var=foo; typeset -n -x ref=var; printenv ref'
> var

That possibility isn't particularly useful nor likely to match what
a user would expect/want. Better to leave the current implementation
(exported namerefs forbidden).

> If we adopt the latter, then "ref=val cmd" behaves as you suggest; the
> environment will be augmented with "ref"->"val". Although, only if "val" is a
> valid identifier. Otherwise, an error will be triggered. However, that's not
> very different from "int=foo cmd" where "int" is an integer parameter, which
> augments the environment with "int"->"0" rather than with "ref"->"foo":
>
> % zsh -c 'typeset -i int; int=foo printenv int'        
> 0
>
> Note that ksh's inline assignments behave exactly as the combined approach
> described above:
>
> % ksh -c 'function f { var=foo; typeset -n ref=var; ref=bar printenv ref; }; f'
> bar
> % ksh -c 'function f { var=foo; typeset -n ref=var; ref=not-an-id printenv ref;
> }; f'
> ksh: f[1]: printenv: not-an-id: invalid variable name
I don't get that error. Looks like a bug, perhaps later
introduced/fixed.

Also of note:

% ksh -c 'function f { var=foo; typeset -n ref=var; ref=bar printenv var; }; f'
bar

In my opinion, an assignment before a command should be the same as a
normal assignment as far as possible with the addition of adding the
export of the explicitly named variable.

So:
var=foo;        typeset -n ref=var;    ref=bar env - export ref=bar
var=foo;        typeset -n -x ref=var; ref=bar env - export ref=var
export var=foo; typeset -n ref=var;    ref=bar env - export ref=bar var=bar

A normal assignment to a reference affects the target variable. Only
with -n options to typeset/unset etc would it be apparent that you
have a reference. But it is most intuitive if the extra export for
assignments before a command apply to what is explicitly named so I
would only export var in the latter case where it is already marked for
export (and it's value should be restored afterwards). I would export
ref in all three cases because it has been named.

We allow a nameref to be created without a target and the first
assignment then sets the reference so, e.g:
typeset -n ref; var=foo; ref=var env - export ref=foo
I'd want that to restore ref pointing nowhere after the command ends.

Oliver




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