И это всё МОЁ

Hi, All!

Светит мне разработка некоторой системы скриптов на баше, на пару тысяч строк. Не надо сразу писать, что такое не стоит писать на баше — это условие задачи, и ставил его не я.

И решил я по такому поводу попробовать широко распространенный совет: «everything is function». А если придерживаться другой популярной концепции, «everything is local», и третьей («arrays wherever possible»;), то тут возникает вопрос о передаче параметров внутрь функции, и о добыче результатов из нее.

Насколько мне известно, баш не обладает возможностями передать массив как массив — штатная передача внутрь как "${array[*]}" разворачивает массив в строку, что обесценивает оригинальную идею.

Можно передавать внутрь ссылку на массив. Но, во-первых, это только с v4.3 работает. Во-вторых, вот способ, который мне понравился больше:

#!/bin/bash

set -o nounset
set -o errexit
set -o pipefail

f1() {
local var1="${f1_data[var1]}"
local ttt

local i=0
while [[ "${f1_data[var2.$i]:-}" ]]; do
ttt="${ttt:-} ${f1_data[var2.$i]}"
let i=$i+1
done

ttt="${ttt:-} --- ${var1}"
eval "$1='${ttt}'"

unset f1_data
}

main() {
local -A f1_data=(
[var1]="v1"
[var2.0]="bebe"
[var2.1]="oo"
[var2.2]="rwx"
)
local result_var="some default"

f1 result_var \
|| echo "ALARM!" >&2

echo "And the result is \"${result_var}\"!"
}

main

Т.е. непосредственно перед вызовом функции все, что ей надо, засовывается в массив с именем [function_name]_data, который обнуляется в конце работы функции. Я использовал ассоциативный массив, но это просто мне так больше нравится.

Да, и про передачу значения наружу тоже в этом же примере.

Использование eval позволяет избавиться от необходимости передавать значение наружу через echo что, в свою очередь, позволяет изящнее организовать обработку ошибок вызова функций.

Ваше мнение?

Буду благодарен за критику и советы.








 , ,