Re: 4.4 change in behavior from 4.3: how to catch unset when using ${#length}
On 11/7/16 4:49 AM, Dan Douglas wrote: > On Sun, Nov 6, 2016 at 3:46 PM, Chet Rameywrote: >> 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}
On 11/1/16 5:57 AM, Dan Douglas wrote: > On Mon, Oct 24, 2016 at 8:25 AM, Chet Rameywrote: >> 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}
On Mon, Oct 24, 2016 at 8:25 AM, Chet Rameywrote: > 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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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