Re: Global variable modification by nameref chain

2016-06-09 Thread Dan Douglas
On Thu, Jun 9, 2016 at 4:34 AM, Dan Douglas  wrote:
> How about just doing it similar to the way mksh resolves arithmetic
> variable loops? As each variable is visited, add it to a list (or hash
> set) and check whether that node was already visited. That should work
> without having to consider scope issues.
>
> $ mksh -c 'a=b b=c c=d d=1; echo $((a))'
> 1
> $ mksh -c 'a=b b=c c=d d=a; echo $((a))'
> mksh: a: expression recurses on parameter 'a'
>
> This nicely says which variable was to blame. I've noticed bash devel
> right now can give messages about "invalid identifiers" which are
> technically valid in most contexts so it's tough to track down
> problems in complicated reference chains.

Sorry one more follow-up. I should note bash has allowed deep
recursion in variable loops for ages using `${!var}` indirection, even
for arrays, and so long as you were careful about unbounded recursion
that never caused a problem before. This would be a
backwards-compatibility breaker if it applied generally. I don't think
namerefs need to be fantastically different from the old indirection
semantics so long as we're ignoring scope.

The only difference between namerefs and old-style indirection is that
an individual array element can't be a nameref and a nameref can't be
an array, so you need to prevent something like this which bash
already does...

 $ bash -c 'typeset -n a=b b; b=a[1]; a=foo; typeset -p a b' # bash 4.3
declare -a a='([1]="foo")'
declare -n b="a[1]"
 $ ./bash -c 'typeset -n a=b b; b=a[1]; typeset -p a b; a=foo' # 4.4
declare -n a="b"
declare -n b="a[1]"
./bash: line 0: `a[1]': not a valid identifier

(That's the confusing error mentioned previously btw)



Re: Global variable modification by nameref chain

2016-06-09 Thread Dan Douglas
How about just doing it similar to the way mksh resolves arithmetic
variable loops? As each variable is visited, add it to a list (or hash
set) and check whether that node was already visited. That should work
without having to consider scope issues.

$ mksh -c 'a=b b=c c=d d=1; echo $((a))'
1
$ mksh -c 'a=b b=c c=d d=a; echo $((a))'
mksh: a: expression recurses on parameter 'a'

This nicely says which variable was to blame. I've noticed bash devel
right now can give messages about "invalid identifiers" which are
technically valid in most contexts so it's tough to track down
problems in complicated reference chains.



Re: Global variable modification by nameref chain

2016-06-09 Thread Dan Douglas
On Sat, Jun 4, 2016 at 5:48 PM, Grisha Levit  wrote:
> On May 23, 2016 1:42 PM, "Chet Ramey"  wrote:
>> > Should the assignment work?  I'm considering changing the
>> > assignments to
>> > work more like the references.
>> >
>> > I think it would be useful for the assignment to work, as that allows
>> > functions to take variable names as arguments without worrying about
>> > name
>> > collisions.
>>
>> I don't like the fact that variable binding simply ignores nameref loops
>> and treats them the same as the variable not being found.  That's the
>> difference here.
>
> What if (in a function scope) a nameref self-reference were unambiguously
> treated as referring to a variable in the next higher scope, other that
> declare [+-] on an existing ref?

I've thought about this as a workaround but resolving loops that way
will probably lead to problems. Needless to say I prefer doing it the
way I previously described where ref=ref and ref=$1 are distinct.
That's separate from the subject of nameref loops between locals of
the same scope of course.

You can already see some of the eventual problems in ksh if you try to
define a nameref within a compound that points to a local and pass the
compound by reference or copy it between functions using typeset
-c/-m. It's a huge mess of bugs.