Re: namref dicussion continued: [PATCH] export -r reference

2016-05-08 Thread Dan Douglas
On Sun, May 8, 2016 at 6:03 PM, Chet Ramey  wrote:
> On 5/5/16 6:02 PM, Dan Douglas wrote:
>> On Thu, May 5, 2016 at 2:46 AM, Piotr Grzybowski  wrote:
>>>  ok, so Dan wants this patch.
>>
>> Yes I think your bash patch is probably an improvement at least in
>> this particular case.
>>
>>> Maybe you can comment on wether the patches are valid.
>>
>> The posix export and readonly don't produce locally scoped variables
>> at all, so it's expected that e.g. `typeset -x` and `export` will
>> differ.
>
> This is a different topic entirely, since neither of the examples
> we're considering take place within a function.  Scoping isn't an
> issue.

Sure I agree that scope isn't the issue. That's was the main point of
my message. I was trying to explain is that ksh does allow -x in
combination with pre-existing references in some contexts, but the
only way to demonstrate that is by calling a function.



Re: namref dicussion continued: [PATCH] export -r reference

2016-05-08 Thread Chet Ramey
On 5/4/16 12:30 PM, Piotr Grzybowski wrote:
> Hey,
> 
>  after another discussion with Grisha, and following one of his remarks, I 
> kindly request your opinion on the attached patch (like: bad, not needed, 
> already done, weak as it stands, harmful, etc.). It addresses the exporting 
> of identifiers with have nameref attribute set.
>  at the moment we have:
> 
> #a=10; declare -nx ra=a; bash -c 'echo "a:$a, ra:$ra, ra_excl:${!ra}."' 
> a:, ra:a, ra_excl:.
> #a=10; declare -n ra=a; export ra; bash -c 'echo "a:$a, ra:$ra, 
> ra_excl:${!ra}."'
> a:10, ra:a, ra_excl:10

I'm not going to add another option to export before bash-4.4 is released.
This discussion, as useful as it's been, has already delayed the release
too long.

The above behavior is a pretty straightforward application of the nameref
rules: in the first case, ra is assigned `a' but never dereferenced; in
the second case, `ra' is dereferenced when used as the argument to
`export'.  `unset' works the same way.  bash and ksh93 work the same with
the second case, though ksh93, for some reason, doesn't allow -nx in any
combination as options to typeset.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: namref dicussion continued: [PATCH] export -r reference

2016-05-08 Thread Chet Ramey
On 5/5/16 6:02 PM, Dan Douglas wrote:
> On Thu, May 5, 2016 at 2:46 AM, Piotr Grzybowski  wrote:
>>  ok, so Dan wants this patch.
> 
> Yes I think your bash patch is probably an improvement at least in
> this particular case.
> 
>> Maybe you can comment on wether the patches are valid.
> 
> The posix export and readonly don't produce locally scoped variables
> at all, so it's expected that e.g. `typeset -x` and `export` will
> differ.

This is a different topic entirely, since neither of the examples
we're considering take place within a function.  Scoping isn't an
issue.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: namref dicussion continued: [PATCH] export -r reference

2016-05-05 Thread Dan Douglas
Oh I see you talked about some of this already in the "chained
nameref" thread. I haven't read that one yet... I wonder why `export
-r` requires a different solution because it's pretty much the same
underlying problem.



Re: namref dicussion continued: [PATCH] export -r reference

2016-05-05 Thread Dan Douglas
On Thu, May 5, 2016 at 2:46 AM, Piotr Grzybowski  wrote:
>  ok, so Dan wants this patch.

Yes I think your bash patch is probably an improvement at least in
this particular case.

> Maybe you can comment on wether the patches are valid.

The posix export and readonly don't produce locally scoped variables
at all, so it's expected that e.g. `typeset -x` and `export` will
differ.

This is yet another problem that's better solved by immutable C++-like
references. At least, the problem goes away when variables are passed
explicitly.

The exact mechanism isn't really documented. When ksh determines that
a nameref assignment is to a positional parameter during evaluation,
you get a completely different type of reference. That is, if `$1`
expands to `x`, then `typeset -n ref=$1` and `typeset -n ref=x` aren't
equivalent like they are in bash.  In the former case, any use of
`ref` except for `typeset +n` and `unset -n` applies to the exact
object that `$1` referred to at the time the reference was created,
even if it's another nameref in which case that reference is followed.
The latter gives you a bash-like dynamic reference that points to
somewhere within either the current scope or the global scope (due to
static scoping) unless it happens to point to another reference
parameter of course.

When you changed that `typeset` line to `export -r _x`, things become
less clear. Ksh sees that _x is a reference parameter and because of
the rules it does the only thing that makes sense which is apply the
export attribute to whatever was passed to the function for both
`export` or `typeset -x`, though there may be some other differences
between those.

Bash on the other hand never does what you'd want for either `export`
or `typeset -x`. For typeset, it tears down the reference and
redefines it as a new local with the export attribute. It does that
indiscriminately for any usage of typeset, which means you can't
correctly modify an attribute by reference in bash. If you actually
wanted that result, the correct way would be to first use `typeset +n
_x` followed by `typeset -x _x`. If you choose `export`, the correct
behavior is even less clear thanks to dynamic scope.

Your patch is a partial solution that makes `export` modify the
attribute in the way you would expect in the absence of the reference
parameter feature. Ignoring namerefs, the only other way for bash to
modify the attribute of the currently visible dynamically scoped local
without declaring a new local is to use export, which is why bash
behaves as it did. This solution doesn't solve the same problem for
attributes other than export and readonly. Bash can't use e.g.
`typeset -u` by reference. It also doesn't solve the many other
problems caused by this like name conflicts.



Re: namref dicussion continued: [PATCH] export -r reference

2016-05-05 Thread Piotr Grzybowski

 ok, a small correction, the problem lies in exportscope:40, but none of the 
patches mentioned solve it, the same behaviour of the test can be recovered 
with just export instead of declare on this line (at least proves that the 
patches dont break it ;-)). some other make_local_variable issue I guess.

pg


On 5 May 2016, at 09:46, Piotr Grzybowski wrote:

> 
> ok, so Dan wants this patch.
> I took a look at your script, there are two cases it addresses: exporting 
> nameref and doing it from inside the function scope, I applied both patches:
> 
> nameref masking in scope:
> https://lists.gnu.org/archive/html/bug-bash/2016-05/msg00012.html
> 
> exporting namerefs:
> https://lists.gnu.org/archive/html/bug-bash/2016-05/msg00024.html
> 
> and with this modification to your script:
> 
> diff --git a/exportscope b/exportscope
> index 05bae73..0125681 100644
> --- a/exportscope
> +++ b/exportscope
> @@ -37,7 +37,8 @@ function h {
>;;
>2)
>typeset -n _x=$2
> -   typeset -x _x='in h2'
> +   export -r _x;
> +   _x='in h2';
>eval "$showEnv" h2
>esac
> }
> @@ -75,4 +76,4 @@ for sh in bash ksh mksh zsh; do
>printf '%s\n\n' "$("$sh" -c "$code" -- "$sh" 2>&1)"
> done
> 
> You can get (difference in test 3):
> 
> #./exportscope 
> bash test 1:
>subprocess f: declare -x x="in f"
>local f: declare -x x="in f"
>global: declare -x x="global"
> bash test 2:
>subprocess g: declare -x x="in g"
>subprocess f: declare -x x="in f"
>local f: declare -x x="in f"
>local g: declare -x x="in g"
>global: declare -- x="unset"
> bash test 3:
>subprocess h2: declare -x x="in h2"
>subprocess h1: declare -x x="in h2"
>local h1: declare -x x="in h2"
> 
> Maybe you can comment on wether the patches are valid.
> 
> cheers,
> pg
> 
> 
> 
> On 4 May 2016, at 22:40, Dan Douglas wrote:
> 
>> Yeah I was just looking for this old script last night and just found it :)
>> 
>> https://gist.github.com/ormaaj/04923e11e8bdc27688ad
>> 
>> If you scroll down to the output for "test 3" where "h" gets called
>> and passes a local "x" to a function that creates a reference to it
>> and exports the reference you can see that bash calls "x" unset in
>> both the first and second scope. As I recall we were discussing the
>> way exported locals interact between scopes at the time, not namerefs,
>> but I added the case for namerefs since I wasn't sure how this should
>> work. I should probably run it again with the current devel branch.
>> 
>> Even though bash doesn't yet support references for parameters like
>> ksh93, neither does mksh, which also shows differences from bash.
> 




Re: namref dicussion continued: [PATCH] export -r reference

2016-05-05 Thread Piotr Grzybowski

 ok, so Dan wants this patch.
 I took a look at your script, there are two cases it addresses: exporting 
nameref and doing it from inside the function scope, I applied both patches:

nameref masking in scope:
https://lists.gnu.org/archive/html/bug-bash/2016-05/msg00012.html

exporting namerefs:
https://lists.gnu.org/archive/html/bug-bash/2016-05/msg00024.html

and with this modification to your script:

diff --git a/exportscope b/exportscope
index 05bae73..0125681 100644
--- a/exportscope
+++ b/exportscope
@@ -37,7 +37,8 @@ function h {
;;
2)
typeset -n _x=$2
-   typeset -x _x='in h2'
+   export -r _x;
+   _x='in h2';
eval "$showEnv" h2
esac
 }
@@ -75,4 +76,4 @@ for sh in bash ksh mksh zsh; do
printf '%s\n\n' "$("$sh" -c "$code" -- "$sh" 2>&1)"
 done

You can get (difference in test 3):

#./exportscope 
bash test 1:
subprocess f: declare -x x="in f"
local f: declare -x x="in f"
global: declare -x x="global"
bash test 2:
subprocess g: declare -x x="in g"
subprocess f: declare -x x="in f"
local f: declare -x x="in f"
local g: declare -x x="in g"
global: declare -- x="unset"
bash test 3:
subprocess h2: declare -x x="in h2"
subprocess h1: declare -x x="in h2"
local h1: declare -x x="in h2"

 Maybe you can comment on wether the patches are valid.

cheers,
pg



On 4 May 2016, at 22:40, Dan Douglas wrote:

> Yeah I was just looking for this old script last night and just found it :)
> 
> https://gist.github.com/ormaaj/04923e11e8bdc27688ad
> 
> If you scroll down to the output for "test 3" where "h" gets called
> and passes a local "x" to a function that creates a reference to it
> and exports the reference you can see that bash calls "x" unset in
> both the first and second scope. As I recall we were discussing the
> way exported locals interact between scopes at the time, not namerefs,
> but I added the case for namerefs since I wasn't sure how this should
> work. I should probably run it again with the current devel branch.
> 
> Even though bash doesn't yet support references for parameters like
> ksh93, neither does mksh, which also shows differences from bash.




Re: namref dicussion continued: [PATCH] export -r reference

2016-05-04 Thread Dan Douglas
Yeah I was just looking for this old script last night and just found it :)

https://gist.github.com/ormaaj/04923e11e8bdc27688ad

If you scroll down to the output for "test 3" where "h" gets called
and passes a local "x" to a function that creates a reference to it
and exports the reference you can see that bash calls "x" unset in
both the first and second scope. As I recall we were discussing the
way exported locals interact between scopes at the time, not namerefs,
but I added the case for namerefs since I wasn't sure how this should
work. I should probably run it again with the current devel branch.

Even though bash doesn't yet support references for parameters like
ksh93, neither does mksh, which also shows differences from bash.



namref dicussion continued: [PATCH] export -r reference

2016-05-04 Thread Piotr Grzybowski
Hey,

 after another discussion with Grisha, and following one of his remarks, I 
kindly request your opinion on the attached patch (like: bad, not needed, 
already done, weak as it stands, harmful, etc.). It addresses the exporting of 
identifiers with have nameref attribute set.
 at the moment we have:

#a=10; declare -nx ra=a; bash -c 'echo "a:$a, ra:$ra, ra_excl:${!ra}."' 
a:, ra:a, ra_excl:.
#a=10; declare -n ra=a; export ra; bash -c 'echo "a:$a, ra:$ra, 
ra_excl:${!ra}."'
a:10, ra:a, ra_excl:10

so either you get reference value exported (not very useful, and probably not 
the intent when typing declare -nx reference=variable;), or you get the 
referenced variable exported, which is not necessarily expected, together with 
the variable with the reference value.

The patch makes both of them work the same, and resolving the reference at 
export:

bash-4.4$ a=10; declare -nx ra=a; bash -c 'echo "a:$a, ra:$ra, 
ra_excl:${!ra}."' 
a:, ra:10, ra_excl:.
bash-4.4$ a=10; declare -n ra=a; export ra; bash -c 'echo "a:$a, ra:$ra, 
ra_excl:${!ra}."'
a:, ra:10, ra_excl:.

and also introduces a way to recover the current behaviour with the exporting 
of the target variable:

bash-4.4$ a=10; declare -n ra=a; export -r ra; bash -c 'echo "a:$a, ra:$ra, 
ra_excl:${!ra}."'
a:10, ra:10, ra_excl:.

there are of course other possibilities to consider, but I agree with Grisha, 
that it is worthy of at least taking a look.

cheers,
pg






follow_references_on_export.patch
Description: Binary data