Skip to content

Instantly share code, notes, and snippets.

@sstephenson
Last active January 30, 2017 01:40
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sstephenson/5350332 to your computer and use it in GitHub Desktop.
Save sstephenson/5350332 to your computer and use it in GitHub Desktop.
`super` in Bash
#!/usr/bin/env bash
source super.bash
foo() {
echo hello
}
super_function foo
foo() {
super
echo world
}
super_function foo
foo # prints "hello\nworld"
is_function() {
[ "$(type -t "$1" || true)" = "function" ]
}
function_body() {
local name="$1"
if is_function "$name"; then
local body="$(declare -f "$name")"
body="${body#*{}"
echo "${body%\}}"
else
echo "no such function \`$name'" >&2
return 1
fi
}
define_function() {
local name="$1"
local body="$2"
eval "${name}() { ${body}; }"
}
alias_function() {
local src="$1"
local dst="$2"
define_function "$dst" "$(function_body "$src")"
}
rename_function() {
local src="$1"
local dst="$2"
alias_function "$src" "$dst"
unset -f "$src"
}
chain_function() {
local name="$1"
local prefix="$2"
local prefix_name="${prefix}${name}"
if is_function "$prefix_name"; then
chain_function "$prefix_name" "$prefix"
fi
rename_function "$name" "$prefix_name"
}
super_function() {
local name="$1"
local body="$(function_body "$name")"
local wrapped_body='
local __last_super_function="$__super_function"
__super_function="__super_$FUNCNAME"
local __super_result=0
{'"$body"';} || __super_result="$?"
__super_function="$__last_super_function"
return "$__super_result"'
if ! is_function "__super_$name"; then
define_function "__super_$name" 'echo "super: superfunction not found" >&2; return 1'
fi
chain_function "$name" __super_
define_function "__super_$name" "$wrapped_body"
define_function "$name" '"__super_$FUNCNAME" "$@"'
}
super() {
if is_function "$__super_function"; then
"$__super_function" "$@"
else
echo "super: must be called from inside a superfunction" >&2
return 1
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment