bash 中的“继承”;有没有办法在重写函数中调用 super (无需 eval)?

bash 中的“继承”;有没有办法在重写函数中调用 super (无需 eval)?

给定文件m.sh

f() {
  echo foo
}

g() {
  f | sed -r 's/^|$/:/g' # random work
}

e.sh

. m.sh

old_f="$(type f | sed '3,$!d')"

f() {
  echo "$(eval "$old_f")bar"
}

g

有没有比使用typeeval从重写函数调用旧函数更好的解决方案,同时保持相同的名称,以便其他函数中的引用仍然有效?

两者m.sh都是e.sh同一个项目的一部分,因此我们可以m.sh放心修改。

答案1

我突然想到我可以这样做:

f_1() {
  echo foo
}

f() { f_1 "$@"; }

g() {
  f | sed -r 's/^|$/:/g' # random work
}
. m.sh

f_2() {
  echo "$(f_1)bar"
}

f() { f_2 "$@"; }

g

不幸的是,这需要修改m.sh以添加这样的样板,但至少它避免了使用typeeval

通过使用第一个定义将其定义一次,可以避免手动重新定义f()以增加数量:

f() {
  "$(last_version_of_function "${FUNCNAME[0]}")" "$@"
}

通过使用这些定义:

reverse_identifier_words() {
  awk -F_ '
    BEGIN {
      OFS="_"
    }
    {
      for (i = 1; i <= NF / 2; i++) {
        t = $i
        $i = $(NF - i + 1)
        $(NF - i + 1) = t
      }
      print
    }
  '
}

last_version_of_function() {
  declare -F \
  | grep -Eo "\b${1}_[0-9]+\$" \
  | reverse_identifier_words \
  | sort -rn -t_ -k1 \
  | head -n1 \
  | reverse_identifier_words
}

这样,e.sh只需执行以下操作即可覆盖:

. m.sh

f_2() {
  echo "$(f_1)bar"
}

g

相关内容