web-dev-qa-db-ja.com

zsh:変数が理由もなく設定解除される

どういうわけか、vを呼び出した後にfが設定解除されます。

$ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v'
+zsh:1> v=1
+zsh:1> f
+f:0> local v
+f:0> v=2 +f:0> true
+zsh:1> typeset -p v
zsh:typeset:1: no such variable: v

これが私のオリジナルの複製レポートの 要点 です。

email [email protected] しましたが、まだ返信がありません。

1
HappyFace

それは確かにバグでした。あなたはそれを報告するために正しいことをしました。

その後、このコミットによって修正されました: https://sourceforge.net/p/zsh/code/ci/d946f22a4cd2eed0f3a67881cfa57c805703929c/ これは次のバージョンに含まれる予定です。

そしてここに zshのメンテナからの説明

On Wed, 2019-08-14 at 10:37 +0100, Stephane Chazelas wrote:
> 2019-08-08 20:38:05 +0430, Aryn Starr:
> Now, that being said, as discussed on U&L it looks like a bug
> indeed and a shorter reproducer is:
> 
> $ zsh -xc 'v=1; f() { local v; v=2 true; }; f; typeset -p v'
> +zsh:1> v=1
> +zsh:1> f
> +f:0> local v
> +f:0> v=2 +f:0> true
> +zsh:1> typeset -p v
> zsh:typeset:1: no such variable: v
> 
> Most likely, that's the "v=2 true" (where "true" is a builtin) that ends up
> unsetting the "v" from the global scope.

Yes, the saved version of "v" that we restore after the builtin is
missing the pointer back to the version of v in the enclosing scope.  So
it's not only not shown as set, it will leak memory.

This simply preserves that pointer in the copy, but this assumes we've
correctly blocked off the old parameter from being altered inside the
function scope --- if we haven't that preserved old pointer is going to
get us into trouble.  However, if we haven't that's already a bug, so
this shouldn't make things worse.

pws

[パッチをスキップしました]

1