how is locale/unset intended to work with dash?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey there.

I'm trying to understand how local/unset works with dash... and it
seems to be a bit dangerous.



In bash, e.g., it seems to work like that:
always the var from the next outer scope is used, when
setting/expanding/unsetting

This implies, that bash "shadows" variables, e.g.

$ x=Vtop
$ f1() { local x=V1 ; f2; echo f1 $x ; }
$ f2() { echo f2 $x ; unset -v x ; echo f2 $x ; }
$ echo top $x
$ f1
$ echo top $x

would give this in bash:
top Vtop
f2 V1
f2 Vtop
f1 Vtop
top Vtop

In other words, as soon as x is unset in f2, the f1()'s local x ceases
to exist and the global x is used.

The only exception is, when it is unset in the same scope level in
which it was made locale:

$ x=Vtop
$ f1() { local x=V1 ; f2; echo f1 $x ; }
$ f2() { local x=V2 ; echo f2 $x ; unset -v x ; echo f2 $x ; }
$ echo top $x
$ f1
$ echo top $x

would give this in bash:
top Vtop
f2 V2
f2
f1 V1
top Vtop


in dash, the first one gives:
top Vtop
f2 V1
f2        <- no unshadowing, so we don't see Vtop here
f1
top Vtop

and the second one:
top Vtop
f2 V2
f2        <- no unshadowing, so we don't see V1 here
f1 V1
top Vtop

=> which actually seems more predictable at first... unset basically
acts on the var from the next outer scope... make it unset in that and
probably any further scopes beneath... but not doesn't "unshadow" the
vars from higher scopes.



However,... things can get far more strange:
$ x=Vtop
$ f1() { local x=V1 ; f2 ; echo f1 $x; }
$ f2() { echo f2 $x; unset -v x; echo f2 $x; f3 ; echo f2 $x; }
$ f3() { echo f3 $x; unset -v x; echo f3 $x; }
$ echo top $x
vf1
$ echo top $x

which gives in dash:

top Vtop
f2 V1
f2
f3
f3
f2
f1
top Vtop   <- shouldn't that have been unset by the f3’s unset?
              f1’s x was already gone by then

Is there some kind of "barrier" in dash? Like when there once was a
local variable of some name in some scope, even if that has already
been unset, one cannot go any higher, not even with unset itself?

Could that perhaps be added to the documentation?




btw: in bash the above would give:
top Vtop
f2 V1
f2 Vtop
f3 Vtop
f3
f2
f1
top
=> which is what one would expect given how bash documents unset and
this "unshadowing"


And bash has - it seems - even another speciality:
$ x=Vtop
$ f1() { local x=V1 ; f2 ; echo f1 $x; }
$ f2() { echo f2 $x; unset -v x; echo f2 $x; f3 ; echo f2 $x; }
$ f3() { local x=V3; echo f3 $x; unset -v x; echo f3 $x; }
$ echo top $x
$ f1
$ echo top $x
gives:
top Vtop
f2 V1
f2 Vtop
f3 V3
f3
f2 Vtop
f1 Vtop
top Vtop

=> when the unset is in the *same* scope level as the `local` ... it
doesn't "unshadow".


$ x=Vtop
$ f1() { local x=V1 ; f2 ; echo f1 $x; }
$ f2() { local x=V2; echo f2 $x; unset -v x; echo f2 $x; f3 ; echo f2 $x; }
$ f3() { echo f3 $x; unset -v x; echo f3 $x; }
$ echo top $x
$ f1
$ echo top $x
gives:
top Vtop
f2 V2
f2       <- was unset at the same level, thus no unshadowing
f3       <- apparently also works at levels beneath
f3 V1    <- but when that unsets again, it unshadows again
f2 V1    <- and this even on the higher level, where it didn't
f1 V1       before,.. that one I found quite unpredictable
top Vtop



I don't even dare to say which is better ;-) ... and I know `local` is
not standardised... but given that it's widely used... wouldn't it be
beneficial if bash/dash (and hopefully others) do pretty much the same?




Cheers,
Chris.



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux