[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Awkward behavior of empty arrays
From: |
Andy Chu |
Subject: |
Re: [Help-bash] Awkward behavior of empty arrays |
Date: |
Thu, 31 Aug 2017 09:16:46 -0700 |
On Thu, Aug 31, 2017 at 7:47 AM, Chet Ramey <address@hidden> wrote:
>
> > 1. Never use anything that isn't in parentheses on the RHS of an array
> > initialization.
>
> This is essentially an attempt to avoid the implicit use of subscript 0.
>
Yes I'm suggesting a style where all implicit conversions are avoided (from
the POV of someone coming from another programming language). If you can
see a case where implicit conversions happen using the rules I gave, that's
a bug :)
As I just wrote, avoiding
declare -a A=x
in favor of:
declare -a A=(x)
is analogous to avoiding "$A" in favor of "{$A[0]}".
>
>
> > "${A[*]}"
> > ${A[*]}
> These are useful in the same way that $* and "$*" are useful.
>
I actually never use $* "$*" $@, or ${A[*]} "${A[*]}" address@hidden in any of
my
programs. I believe they can always be expressed using different (IMO
clearer) mechanisms.
Consider this:
$ set -- foo '*.sh' bar
There are only 3 possibilities from the four constructs (AFAICT $* is
identical to $@):
$ argv "$@"
['foo', '*.sh', 'bar']
$ argv $@
['foo', 'bad.sh', 'local.sh', 'setup.sh', 'bar']
$ argv "$*"
['foo *.sh bar']
$ argv
$*
['foo', 'bad.sh', 'local.sh', 'setup.sh', 'bar']
These 3 possibilities can always be achieved as follows:
$ argv "$@"
['foo', '*.sh', 'bar']
$ joined="$@" # explicit join
$ argv "$joined"
['foo *.sh bar']
$ argv $joined
['foo', 'bad.sh', 'local.sh', 'setup.sh', 'bar']
So I have used nothing but "$@" to generate all 3 possibilities. Similarly
for "address@hidden".
>
>
> > In particular, don't expect to compare arrays with [[.
> >
> > $ declare -a A=(A B C D)
> > $ declare -a B=('A B' 'C D')
> >
> > $ echo "address@hidden"
> > 4
> > $ echo "address@hidden"
> > 2
> >
> > # arrays compare equal because they're coerced to strings before
> comparison
> > $ [[ "address@hidden" == "address@hidden" ]]; echo $?
> > 0
>
> Because the operands in [[ commands don't undergo word splitting.
>
Yes, it depends how you think about it from the implementation POV. In
OSH, variables are represented by a discriminated union (in ML-like syntax):
value =
Undef
| Str(string s)
| StrArray(string* strs)
So when I do [[ "address@hidden" == "address@hidden" ]], I actually have to
JOIN the
arrays first to main compatibility with bash (there could be a flag to turn
this off.)
So it's not just lack of splitting, but ADDING joining (i.e. coerce an
array to string). But if bash stores arrays as FLAT strings internally,
and only does splitting upon splicing into an argv array, then you can
think of it as lack of splitting.
Andy
Re: [Help-bash] Awkward behavior of empty arrays, Chet Ramey, 2017/08/31
Re: [Help-bash] Awkward behavior of empty arrays, Chris F.A. Johnson, 2017/08/31