Il problema di base qui è che gli sviluppatori bash che hanno progettato / implementato array hanno davvero fregato il cane. Decisero che ${array}
era solo una scorciatoia per ${array[0]}
, che fu un brutto errore. Soprattutto se si considera che ${array[0]}
non ha significato e viene valutata la stringa vuota se il tipo di array è associativo.
L'assegnazione di un array assume la forma in array=(value1 ... valueN)
cui value ha la sintassi [subscript]=string
, assegnando così un valore direttamente a un indice specifico dell'array. Questo lo rende così ci possono essere due tipi di array, indicizzati numericamente e hash indicizzati (chiamati array associativi nel linguaggio bash). Inoltre, consente di creare array sparsi indicizzati numericamente. Lasciare la [subscript]=
parte è una scorciatoia per un array indicizzato numericamente, a partire dall'indice ordinale di 0 e incrementando con ogni nuovo valore nell'istruzione di assegnazione.
Pertanto, ${array}
dovrebbe valutare l' intero array, gli indici e tutti. Dovrebbe valutare l'inverso della dichiarazione di assegnazione. Qualsiasi maggiore CS del terzo anno dovrebbe saperlo. In tal caso, questo codice funzionerebbe esattamente come ci si aspetterebbe che:
declare -A foo bar
foo=${bar}
Quindi, il passaggio di matrici per valore alle funzioni e l'assegnazione di un array a un altro funzionerebbe come impone il resto della sintassi della shell. Ma poiché non hanno fatto questo bene, l'operatore di assegnazione =
non funziona per le matrici e le matrici non possono essere passate in base al valore alle funzioni o alle subshells o all'output in generale ( echo ${array}
) senza codice per masticarle.
Quindi, se fosse stato fatto bene, il seguente esempio mostrerebbe come l'utilità degli array in bash potrebbe essere sostanzialmente migliore:
simple=(first=one second=2 third=3)
echo ${simple}
l'output risultante dovrebbe essere:
(first=one second=2 third=3)
Quindi, le matrici potrebbero utilizzare l'operatore di assegnazione e passare per valore alle funzioni e persino ad altri script di shell. Facilmente memorizzabile in uscita su un file e facilmente caricato da un file in uno script.
declare -A foo
read foo <file
Purtroppo, siamo stati delusi da un team di sviluppo bash altrimenti superlativo.
Pertanto, per passare un array a una funzione, esiste davvero solo un'opzione, ovvero utilizzare la funzione nameref:
function funky() {
local -n ARR
ARR=$1
echo "indexes: ${!ARR[@]}"
echo "values: ${ARR[@]}"
}
declare -A HASH
HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function
produrrà il seguente output:
indexes: foo zoom
values: bar fast
Poiché questo passa per riferimento, è anche possibile assegnare alla matrice nella funzione. Sì, l'array a cui si fa riferimento deve avere un ambito globale, ma questo non dovrebbe essere un affare troppo grande, considerando che si tratta di shell scripting. Per passare una matrice indicizzata associativa o sparsa per valore a una funzione è necessario lanciare tutti gli indici e i valori nell'elenco degli argomenti (non troppo utile se si tratta di una matrice di grandi dimensioni) come stringhe singole come questa:
funky "${!array[*]}" "${array[*]}"
e quindi scrivere un sacco di codice all'interno della funzione per riassemblare l'array.