Skip to content

Instantly share code, notes, and snippets.

@NicholasRoge
Last active March 11, 2017 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NicholasRoge/e04a853126b6e7b548891fe978b4e756 to your computer and use it in GitHub Desktop.
Save NicholasRoge/e04a853126b6e7b548891fe978b4e756 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
overload:call()
{
name=$1
shift
overloads="overloads_$name"
eval 'local offset=${#'"$overloads"'[@]}'
while true
do
((offset--))
eval 'local callable=${'"$overloads"'[$offset]}'
if (( $offset == 0 ))
then
break
fi
((offset--))
eval 'local argc=${'"$overloads"'[$offset]}'
if (( $argc > 0 ))
then
((offset-=$argc))
eval 'local argv=( "${'"$overloads"'[@]:$offset:$argc}" )'
for arg in `seq 1 $argc`
do
val=${argv[$(( $arg - 1 ))]}
if [[ "$val" != "${!arg}" ]] && [[ "$val" != "*" ]]
then
callable=
break
fi
done
fi
if [ -n "$callable" ]
then
break
fi
done
if [ -n "$callable" ]
then
eval 'parent() { _'"$name"' "$@"; }'
eval 'call() { '"$callable"'; }'
call "$@"
unset -f parent
else
eval '_'"$name"' "$@"'
fi
eval 'extensions=("${extensions_'"$name"'[@]}")'
for extension in "${extensions[@]}"
do
eval 'call() { '"$extension"'; }'
call "$@"
done
}
overload:init()
{
name="$1"
name_source="$(type $name)"
name_source_lines="$(echo "$name_source" | wc -l)"
name_source="$(echo "$name_source" | head -n $(($name_source_lines - 1)))"
name_source="$(echo "$name_source" | tail -n $(($name_source_lines - 4)))"
eval "_$name() { $name_source; }"
eval "$name() { overload:call $name \"\$@\"; }"
eval 'overloads_'"$name"'=("")'
eval 'extensions_'"$name"'=()'
}
overload:add()
{
if [[ "$1" == '-e' ]]
then
shift
extending=true
else
extending=false
fi
name="$1"
shift
if $extending
then
callable="$1"
eval 'extensions_'"$name"'+=( "$callable" )'
else
# The 'filter' arguments need to be saved in reverse
argv=()
while (( $# > 1 ))
do
argv=( "${argv[@]}" "$1" )
shift
done
callable="$1"
eval 'overloads_'"$name"'+=( "${argv[@]}" ${#argv[@]} "$callable" )'
fi
}
##Overload
#
# Usage:
# overload name [val [val [...]]] callable
# name
# Name of function to be overloaded.
# val
# Values that have to match the arguments of the call
# in order for callable to be called.
# callable
# A callable expression string that will be expanded
# upon call.
#
# Example:
# key_pressed(){echo "key: $1";}
# overload key_pressed "h" 'echo "before"; parent "$@"; echo "after"'
# overload key_pressed "q" exit
# key_pressed a
# > key: a
# key_pressed h
# > before
# > key: h
# > after
# key_pressed q
overload()
{
if [[ "$1" == '-e' ]]
then
shift
local extending=true
else
local extending=false
fi
name="$1"
if (( $# <= 1 ))
then
overload:list "$name"
else
count="$(eval 'printf %i ${#overloads_'"$name"'[@]}')"
if (( $count == 0 ))
then
overload:init $name
fi
if $extending
then
overload:add -e "$@"
else
overload:add "$@"
fi
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment