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

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



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.

In principle, I agree with these requirements however I think that there is an even more imperative requirement, namely that "cmd" must run in exactly the same environment when run with "ref=foo cmd" as when run with "fun() { cmd }; ref=foo fun". This requirement puts severe constraints on what's possible. If you consider only the case "ref=foo cmd", then you could modify the implementation of inline assignments for example to augment the environment with the pair "ref"->"foo" just after the call to addvars and before the execution of "cmd". However, nothing similar is possible for the case "fun() { cmd }; ref=foo fun". Here, your only levers are to modify the parameter table that will be visible to "fun" in such a way that when "fun" executes "cmd", the environment will be the desired one.

For our discussion we should consider the following example:

var=foo
typeset -n ref=var
fun() {
  typeset -p var ref
  printenv var
  printenv ref
}
ref=bar fun

What we need to answer is what should the "typeset -p" and the two "printenv" print. What the implementation of "ref=bar fun" can do is change the value of ref and/or var and modify their flags. We can also decide whether -x is allowed on references and what it has for effect. We could possibly also define one or more new parameter flags (although there are only very few PM bits left).

Technically, it would be possible to go beyond by (ab)using the precomputed environment but I don't think this would be wise.

My understanding of the Zsh language is that whenever an external command is run (with no inline assignments), it is expected to run in an environment that is fully specified by the set of -x flagged parameters present in the scope in which the command is run; an entry N->V is present in that environment if and only if the scope of the command contains an -x flagged parameter named N and the string representation of its value is the string V.

This can be implemented by computing, each time an external command is run, a new environment that contains the names and values of all the -X flagged parameters visible at that moment. The current implementation of Zsh optimizes this by maintaining a precomputed environment. Each time a parameter is flagged with -x, a corresponding entry is added to the precomputed environment and each time the value of an -x flagged parameter is modified, the corresponding entry is updated. Whenever an external command is run, the precomputed environment already contains all the expected entries and can be used as the environment for the command.

Oliver stated that he expects the following:

export var=foo; typeset -n ref=var;    ref=bar env - export ref=bar var=bar

This implies that the inline assignment "ref=bar" should A) assign "bar" to the parameter referred by "ref", here "var" and B) add the entry "ref"->"bar" to the environment of the inline command. This could be achieved by executing "ref=bar" as a normal assignment and then adding the entry "ref"->"bar" to the precomputed environment. The consequence would be that the "precomputed" environment would no longer simply be a precomputation of the environment implied by the -x flagged parameters. It would instead become an entity of its own.

Consider the following example:

% fun() { typeset -p var ref; echo var=$(printenv var); echo ref=$(printenv ref) }
export var=foo; typeset -n ref=var; ref=bar fun
export var=bar
typeset -g -n ref=var
var=bar
ref=bar

In the function "fun", the environment implied by the parameters "var" and "ref" only contains the entry "var"->"bar" but in reality the "precomputed" environment would contain the two entries "var"->"bar" and "ref"->"bar".

Repurposing the precomputed environment into an entity of its own is technically possible but it doesn't look wise to me. I would rather avoid that route.

Philippe



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