Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-11-09 Thread Chet Ramey
On 11/7/16 4:49 AM, Dan Douglas wrote:
> On Sun, Nov 6, 2016 at 3:46 PM, Chet Ramey  wrote:
>> On 11/1/16 5:57 AM, Dan Douglas wrote:
>>> On a possibly related note, would you consider adjusting +, :+, -, :-,
>>> as in "${var[@]+word}" to align with the meaning of [[ -v var[@] ]] as
>>> discussed in 
>>> https://lists.gnu.org/archive/html/bug-bash/2014-11/msg00099.html
>>> ?
>>
>> There's not a compelling reason to break backwards compatibility or to be
>> unnecessarily incompatible with other shells that implement that construct,
>> like ksh93.
> 
> I kind of doubt anybody would know what to expect with them. :+ and :-
> are particularly weird (they don't quite have to do with testing for
> defined variable admittedly).

This is probably true.  I think all the shells with arrays try to treat
${a[@]} in the same way as $@, which gets strange in a "scalar" context.
There was a pretty extensive discussion of the $@ issue on the austin-
group mailing list, which revealed big differences in how shells expand
$@ in a "non-list" context.  I think those differences are reflected in
how those shells expand ${a[@]}.

Chet

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-11-06 Thread Chet Ramey
On 11/1/16 5:57 AM, Dan Douglas wrote:
> On Mon, Oct 24, 2016 at 8:25 AM, Chet Ramey  wrote:
>> On 10/21/16 5:41 PM, L. A. Walsh wrote:
>>> On 4.3 and earlier, at least on arrays, one could have
>>> the illusion of this working w/o complaint -- and returning
>>> 0 when the array was 0-len or unset, or the array length,
>>> otherwise:
>>>
>>>
>>>  echo ${#array[@]:-0}
>>>
>>> But I note it only seemed to work in arrays, and in 4.4 gets a
>>> syntax error:
>>>
>>>  echo ${#array[@]:-0}   bash: ${#array[@]:-0}: bad substitution
>>
>> Because it is a syntax error, and if it were not it would be ambiguous.
>> The ${param:-word} word expansion takes a parameter, not another word
>> expansion, as the object to be expanded.
> 
> On a possibly related note, would you consider adjusting +, :+, -, :-,
> as in "${var[@]+word}" to align with the meaning of [[ -v var[@] ]] as
> discussed in https://lists.gnu.org/archive/html/bug-bash/2014-11/msg00099.html
> ? 

There's not a compelling reason to break backwards compatibility or to be
unnecessarily incompatible with other shells that implement that construct,
like ksh93.

Chet

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-11-01 Thread Dan Douglas
On Mon, Oct 24, 2016 at 8:25 AM, Chet Ramey  wrote:
> On 10/21/16 5:41 PM, L. A. Walsh wrote:
>> On 4.3 and earlier, at least on arrays, one could have
>> the illusion of this working w/o complaint -- and returning
>> 0 when the array was 0-len or unset, or the array length,
>> otherwise:
>>
>>
>>  echo ${#array[@]:-0}
>>
>> But I note it only seemed to work in arrays, and in 4.4 gets a
>> syntax error:
>>
>>  echo ${#array[@]:-0}   bash: ${#array[@]:-0}: bad substitution
>
> Because it is a syntax error, and if it were not it would be ambiguous.
> The ${param:-word} word expansion takes a parameter, not another word
> expansion, as the object to be expanded.

On a possibly related note, would you consider adjusting +, :+, -, :-,
as in "${var[@]+word}" to align with the meaning of [[ -v var[@] ]] as
discussed in https://lists.gnu.org/archive/html/bug-bash/2014-11/msg00099.html
? I've always felt the best use of that expansion would be to test for
a defined array (or any set array element other than arr[0]).
${var[@]+word}, ${var[0]+word}, and ${var+word} are currently
redundant to my knowledge. The latter two I can understand, but var[@]
seems inconsistent.

My best interpretation of the current behaviour is that it copies that
of $@, which doesn't really make sense IMO because arrays may be
sparse. All the effects of ${@+word} make sense but don't translate
well directly to bash arrays. OTOH [[ -v var[@] ]] since bash 4.3
makes a lot of sense to me and I think they would translate well to
the corresponding parameter expansions.



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-29 Thread Chet Ramey
On 10/29/16 2:04 AM, L. A. Walsh wrote:
> 
> 
> Chet Ramey wrote:
>> Come on, don't be willfully obtuse. You know better than this. Posix mode
>> doesn't mean "turning it off does everything the way Linda wants."
>>   
> No, but claiming posix as a backing for features running that are
> not running with posix-mode set, is equally obtuse.

I don't think you understand what Posix mode is.

> Bash is not limited to posix features or behavior -- otherwise there
> would not be a "posix"-mode that forces it into posix behavior.

There are indeed several places where the default operation differs from
Posix, and posix mode addresses those. Since bash is basically a posix
shell, though, there are far more places where the bash defaut behavior is
the Posix behavior.  This is one of those places.

> 
> You can claim a feature is a certain way because posix requires it
> when you are operating in posix-only mode.

Not actually true. I can claim bash implements a particular feature the
way bash implements it. You might not agree with it, but the beauty of
open source is that you can take bash, go off, and use it as a base for
`walsh'.

> 
> bash is advertised as having a default operation that differs from
> the POSIX standard.  If someone is not operating in posix mode, then
> it is a "truism", that operations and features in the non-POSIX mode
> might not comply with POSIX.

They might not.  In this case, they do, and the Posix standard is a
good reference for the behavior.

> I'm not being willfully obtuse -- I'm going by the manpage that says
> bash's default differs from the POSIX standard when the posix mode
> is not active:

I'm not sure what you think this is going to demonstrate.  Bash works as
described in the man page.  The man page and the Posix standard happen to
align on this feature.

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-29 Thread L. A. Walsh



Chet Ramey wrote:

Come on, don't be willfully obtuse. You know better than this. Posix mode
doesn't mean "turning it off does everything the way Linda wants."
  

No, but claiming posix as a backing for features running that are
not running with posix-mode set, is equally obtuse.

Bash is not limited to posix features or behavior -- otherwise there
would not be a "posix"-mode that forces it into posix behavior.

You can claim a feature is a certain way because posix requires it
when you are operating in posix-only mode.

bash is advertised as having a default operation that differs from
the POSIX standard.  If someone is not operating in posix mode, then
it is a "truism", that operations and features in the non-POSIX mode
might not comply with POSIX. 


I'm not being willfully obtuse -- I'm going by the manpage that says
bash's default differs from the POSIX standard when the posix mode
is not active:

--posix
 Change  the behavior of bash where the default operation differs
 from the POSIX standard to match the standard (posix mode).  See
 SEE  ALSO  below  for a reference to a document that details how
 posix mode affects bash's behavior.

From the bash manpage, it is obvious that the default mode is
different from POSIX.  I submit that quoting POSIX
as justification for bash's default-mode behavior is a much better
example of being willfully obtuse, since the manpage clearly says
default-operation is not POSIX.












Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-28 Thread Chet Ramey
On 10/28/16 3:43 PM, L. A. Walsh wrote:

> 
>Please, I'm not running in posix mode, so how would their rules
> apply?  

Because you're using `bash', not `walsh'?

Bash is a posix shell. Would the bash documentation convince you? You
could go read that instead.

> Just because posix defines something a certain way
> doesn't mean it should apply in a non-posix mode shell.

Come on, don't be willfully obtuse.  You know better than this.  Posix mode
doesn't mean "turning it off does everything the way Linda wants."

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-28 Thread L. A. Walsh



Chet Ramey wrote:

On 10/24/16 7:32 PM, L. A. Walsh wrote:

  

   I don't understand the ambiguity.  If param= "#obj[@]", then it
is clear to me that the user wants the length of an array named "obj".



Stop there.  In something like ${#obj[@]}, `param' is `obj[@]'.  The
`${#param}' is a clearly-defined word expansion, separate from the
`[:]-' forms:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

That's what we're talking about here.
  


   Please, I'm not running in posix mode, so how would their rules
apply?  Just because pi=3 under Indiana state rules some number of years
ago, doesn't mean it is.  Just because posix defines something a certain way
doesn't mean it should apply in a non-posix mode shell.





Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-28 Thread Chet Ramey
On 10/24/16 7:32 PM, L. A. Walsh wrote:

>I don't understand the ambiguity.  If param= "#obj[@]", then it
> is clear to me that the user wants the length of an array named "obj".

Stop there.  In something like ${#obj[@]}, `param' is `obj[@]'.  The
`${#param}' is a clearly-defined word expansion, separate from the
`[:]-' forms:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

That's what we're talking about here.

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-24 Thread L. A. Walsh



Chet Ramey wrote:

On 10/21/16 5:41 PM, L. A. Walsh wrote:
  
[previously] one could have the illusion of this working 
w/o complaint -- and returning 0 when the array was 0-len 
or unset, or the array length, otherwise:

 echo ${#array[@]:-0}
But I note it only seemed to work in arrays, and in 4.4 gets a
syntax error:
 echo ${#array[@]:-0}   bash: ${#array[@]:-0}: bad substitution



Because it is a syntax error, and if it were not it would be ambiguous.
The ${param:-word} word expansion takes a parameter, not another word
expansion, as the object to be expanded.
  


   I don't understand the ambiguity.  If param= "#obj[@]", then it
is clear to me that the user wants the length of an array named "obj".
If it doesn't have the [@|*], then the user wants the # of characters
in "obj".  It seems both cases have clearly defined meanings.

   In either case, if the variable isn't set, or if array is unset, then
the length cannot be set.  If the length is not set, the the text to the
right of the ':-' is substituted.

   Alternatively, neither ${#unset} nor ${#unset[@]} should generate
errors (i.e. if the length operator is defined on "unset" variables, then
no error would be generated).  However, if one has "undefined-warnings"
turned on, both of those trigger an undefined warning. 


   If one doesn't have the "undefined-warnings" turned on, then the
"#" operator says that the length of an undefined variable or array
is '0': a dubious result, unless one claims that the '#' "handles" an
undefined(unset) variable and returns its length as '0'.

   If you want '#' to return '0' for undefined/unset objects (vars or 
arrays),

then it shouldn't trigger the "-u: unset variable" exception -- in the same
way one can safely test those names with ${object:-} and not trigger
the "unset-variable exception".

   Either way would work for me -- returning 0 and not triggering the 
error,

or having "#" return "undef/unset" if used with an unset object which could
then be tested as part of a ${object:-} type expansion.

   It seems the ambiguity results from the length operator not returning
results consistent with triggered "unset" errors, no?









Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-24 Thread Chet Ramey
On 10/21/16 5:41 PM, L. A. Walsh wrote:
> On 4.3 and earlier, at least on arrays, one could have
> the illusion of this working w/o complaint -- and returning
> 0 when the array was 0-len or unset, or the array length,
> otherwise:
> 
> 
>  echo ${#array[@]:-0}
> 
> But I note it only seemed to work in arrays, and in 4.4 gets a
> syntax error:
> 
>  echo ${#array[@]:-0}   bash: ${#array[@]:-0}: bad substitution

Because it is a syntax error, and if it were not it would be ambiguous.
The ${param:-word} word expansion takes a parameter, not another word
expansion, as the object to be expanded.

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



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-24 Thread Greg Wooledge
On Fri, Oct 21, 2016 at 09:19:08PM -0700, L. A. Walsh wrote:
> Eduardo Bustamante wrote:
> >what's wrong with?:
> >echo ${#array[@]}

> Not when "-u" is set, which I often have on to help catch misspellings.
> 
> set -u
> echo ${#array[@]}
> bash: array: unbound variable

See http://mywiki.wooledge.org/BashFAQ/112

set -u is almost as bad as set -e.  It's a poorly implemented crutch
which breaks scripts that would otherwise work.

If you're going to file bug reports about your scripts breaking when
you use set -u, you should at least mention that in the initial bug
report.



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-21 Thread Eduardo Bustamante
what's wrong with?:

echo ${#array[@]}

It will return:

- With array=(1 2 3) -> 3
- With array=() -> 0
- With unset array -> 0
- With declare -a array -> 0

Seems to do what you're looking for.



Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-21 Thread L. A. Walsh

Eduardo Bustamante wrote:

what's wrong with?:
echo ${#array[@]}
It will return:
- With array=(1 2 3) -> 3
- With array=() -> 0
- With unset array -> 0
- With declare -a array -> 0

Seems to do what you're looking for.
  


Not when "-u" is set, which I often have on to help catch misspellings.

set -u
echo ${#array[@]}
bash: array: unbound variable

Compare to:

if [[ ${yesno:-""} == yes ]]; then ... fi

# basically wanting 1 test for members, else return 0

if [[ ${array[@]:-"undef"} != undef ]] && ((${#array[@]}))

tnx,
-l





4.4 change in behavior from 4.3: how to catch unset when using ${#length}

2016-10-21 Thread L. A. Walsh

On 4.3 and earlier, at least on arrays, one could have
the illusion of this working w/o complaint -- and returning
0 when the array was 0-len or unset, or the array length,
otherwise:


 echo ${#array[@]:-0}

But I note it only seemed to work in arrays, and in 4.4 gets a
syntax error:

 echo ${#array[@]:-0}  
 bash: ${#array[@]:-0}: bad substitution


Is there any reason why such a syntax wouldn't be workable --
including adding:

echo ${#wordlen:-0}  to allow catching an undefined word?

or is there some other, inline way to do this?

-linda